aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-04 18:23:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-04 18:23:49 -0400
commit5cf65713f87775c548e3eb48dbafa32e12f28000 (patch)
tree117442e28cddebb79246b1c4b871428e50b27fb1 /drivers/hid
parentb7c8e55db7141dcbb9d5305a3260fa0ed62a1bcc (diff)
parent9f17d516416c88dfe18f4deee508fce763ddedb5 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (30 commits) Revert "HID: add support for the Wacom Intuos 4 wireless" HID: fix up Kconfig entry for ACRUX driver HID: add ACRUX game controller force feedback support HID: Force input registration for "VEC footpedal" HID: add HID_QUIRK_HIDINPUT_FORCE HID: hid-input.c: indentation fixes HID: hiddev: use usb_find_interface, get rid of BKL HID: ignore digitizer usage Undefined (0x00) HID: Add support for Conceptronic CLLRCMCE HID: hid-ids.h: Whitespace fixup, align using TABs HID: picolcd: implement refcounting of framebuffer HID: picolcd: do not reallocate memory on depth change HID: picolcd: Add minimal palette required by fbcon on 8bpp HID: magicmouse: Correct parsing of large X and Y motions. HID: magicmouse: report last touch up HID: picolcd: fix deferred_io init/cleanup to fb ordering HID: hid-ids.h: keep vendor ids in alphabetical order HID: add proper support for Elecom BM084 bluetooth mouse HID: magicmouse: enable horizontal scrolling HID: magicmouse: add param for scroll speed ...
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig19
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-axff.c172
-rw-r--r--drivers/hid/hid-core.c8
-rw-r--r--drivers/hid/hid-elecom.c57
-rw-r--r--drivers/hid/hid-ids.h91
-rw-r--r--drivers/hid/hid-input.c21
-rw-r--r--drivers/hid/hid-magicmouse.c96
-rw-r--r--drivers/hid/hid-picolcd.c199
-rw-r--r--drivers/hid/hid-roccat-kone.c25
-rw-r--r--drivers/hid/hid-roccat-kone.h2
-rw-r--r--drivers/hid/hid-roccat.c9
-rw-r--r--drivers/hid/hid-roccat.h2
-rw-r--r--drivers/hid/hid-topseed.c5
-rw-r--r--drivers/hid/hid-wacom.c2
-rw-r--r--drivers/hid/hidraw.c2
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/hid/usbhid/hiddev.c54
18 files changed, 585 insertions, 183 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 434099369058..6369ba7f96f8 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -68,6 +68,14 @@ config HID_A4TECH
68 ---help--- 68 ---help---
69 Support for A4 tech X5 and WOP-35 / Trust 450L mice. 69 Support for A4 tech X5 and WOP-35 / Trust 450L mice.
70 70
71config HID_ACRUX_FF
72 tristate "ACRUX force feedback support"
73 depends on USB_HID
74 select INPUT_FF_MEMLESS
75 ---help---
76 Say Y here if you want to enable force feedback support for ACRUX
77 game controllers.
78
71config HID_APPLE 79config HID_APPLE
72 tristate "Apple" if EMBEDDED 80 tristate "Apple" if EMBEDDED
73 depends on (USB_HID || BT_HIDP) 81 depends on (USB_HID || BT_HIDP)
@@ -148,6 +156,12 @@ config HID_EGALAX
148 ---help--- 156 ---help---
149 Support for the eGalax dual-touch panel. 157 Support for the eGalax dual-touch panel.
150 158
159config HID_ELECOM
160 tristate "ELECOM"
161 depends on BT_HIDP
162 ---help---
163 Support for the ELECOM BM084 (bluetooth mouse).
164
151config HID_EZKEY 165config HID_EZKEY
152 tristate "Ezkey" if EMBEDDED 166 tristate "Ezkey" if EMBEDDED
153 depends on USB_HID 167 depends on USB_HID
@@ -417,10 +431,11 @@ config SMARTJOYPLUS_FF
417 enable force feedback support for it. 431 enable force feedback support for it.
418 432
419config HID_TOPSEED 433config HID_TOPSEED
420 tristate "TopSeed Cyberlink remote control support" 434 tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
421 depends on USB_HID 435 depends on USB_HID
422 ---help--- 436 ---help---
423 Say Y if you have a TopSeed Cyberlink or BTC Emprex remote control. 437 Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
438 CLLRCMCE remote control.
424 439
425config HID_THRUSTMASTER 440config HID_THRUSTMASTER
426 tristate "ThrustMaster devices support" 441 tristate "ThrustMaster devices support"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 987fa0627367..46f037f3df80 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -24,6 +24,7 @@ endif
24 24
25obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o 25obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
26obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o 26obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
27obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o
27obj-$(CONFIG_HID_APPLE) += hid-apple.o 28obj-$(CONFIG_HID_APPLE) += hid-apple.o
28obj-$(CONFIG_HID_BELKIN) += hid-belkin.o 29obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
29obj-$(CONFIG_HID_CANDO) += hid-cando.o 30obj-$(CONFIG_HID_CANDO) += hid-cando.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
32obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 33obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
33obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o 34obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o
34obj-$(CONFIG_HID_EGALAX) += hid-egalax.o 35obj-$(CONFIG_HID_EGALAX) += hid-egalax.o
36obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
35obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 37obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
36obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 38obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
37obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 39obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c
new file mode 100644
index 000000000000..f42ee140738a
--- /dev/null
+++ b/drivers/hid/hid-axff.c
@@ -0,0 +1,172 @@
1/*
2 * Force feedback support for ACRUX game controllers
3 *
4 * From what I have gathered, these devices are mass produced in China
5 * by several vendors. They often share the same design as the original
6 * Xbox 360 controller.
7 *
8 * 1a34:0802 "ACRUX USB GAMEPAD 8116"
9 * - tested with a EXEQ EQ-PCU-02090 game controller.
10 *
11 * Copyright (c) 2010 Sergei Kolzun <x0r@dv-life.ru>
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/input.h>
31#include <linux/slab.h>
32#include <linux/usb.h>
33#include <linux/hid.h>
34
35#include "hid-ids.h"
36#include "usbhid/usbhid.h"
37
38struct axff_device {
39 struct hid_report *report;
40};
41
42static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
43{
44 struct hid_device *hid = input_get_drvdata(dev);
45 struct axff_device *axff = data;
46 int left, right;
47
48 left = effect->u.rumble.strong_magnitude;
49 right = effect->u.rumble.weak_magnitude;
50
51 dbg_hid("called with 0x%04x 0x%04x", left, right);
52
53 left = left * 0xff / 0xffff;
54 right = right * 0xff / 0xffff;
55
56 axff->report->field[0]->value[0] = left;
57 axff->report->field[1]->value[0] = right;
58 axff->report->field[2]->value[0] = left;
59 axff->report->field[3]->value[0] = right;
60 dbg_hid("running with 0x%02x 0x%02x", left, right);
61 usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
62
63 return 0;
64}
65
66static int axff_init(struct hid_device *hid)
67{
68 struct axff_device *axff;
69 struct hid_report *report;
70 struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
71 struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list;
72 struct input_dev *dev = hidinput->input;
73 int error;
74
75 if (list_empty(report_list)) {
76 dev_err(&hid->dev, "no output reports found\n");
77 return -ENODEV;
78 }
79
80 report = list_first_entry(report_list, struct hid_report, list);
81
82 if (report->maxfield < 4) {
83 dev_err(&hid->dev, "no fields in the report: %d\n", report->maxfield);
84 return -ENODEV;
85 }
86
87 axff = kzalloc(sizeof(struct axff_device), GFP_KERNEL);
88 if (!axff)
89 return -ENOMEM;
90
91 set_bit(FF_RUMBLE, dev->ffbit);
92
93 error = input_ff_create_memless(dev, axff, axff_play);
94 if (error)
95 goto err_free_mem;
96
97 axff->report = report;
98 axff->report->field[0]->value[0] = 0x00;
99 axff->report->field[1]->value[0] = 0x00;
100 axff->report->field[2]->value[0] = 0x00;
101 axff->report->field[3]->value[0] = 0x00;
102 usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
103
104 dev_info(&hid->dev, "Force Feedback for ACRUX game controllers by Sergei Kolzun<x0r@dv-life.ru>\n");
105
106 return 0;
107
108err_free_mem:
109 kfree(axff);
110 return error;
111}
112
113static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
114{
115 int error;
116
117 dev_dbg(&hdev->dev, "ACRUX HID hardware probe...");
118
119 error = hid_parse(hdev);
120 if (error) {
121 dev_err(&hdev->dev, "parse failed\n");
122 return error;
123 }
124
125 error = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
126 if (error) {
127 dev_err(&hdev->dev, "hw start failed\n");
128 return error;
129 }
130
131 error = axff_init(hdev);
132 if (error) {
133 /*
134 * Do not fail device initialization completely as device
135 * may still be partially operable, just warn.
136 */
137 dev_warn(&hdev->dev,
138 "Failed to enable force feedback support, error: %d\n",
139 error);
140 }
141
142 return 0;
143}
144
145static const struct hid_device_id ax_devices[] = {
146 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), },
147 { }
148};
149MODULE_DEVICE_TABLE(hid, ax_devices);
150
151static struct hid_driver ax_driver = {
152 .name = "acrux",
153 .id_table = ax_devices,
154 .probe = ax_probe,
155};
156
157static int __init ax_init(void)
158{
159 return hid_register_driver(&ax_driver);
160}
161
162static void __exit ax_exit(void)
163{
164 hid_unregister_driver(&ax_driver);
165}
166
167module_init(ax_init);
168module_exit(ax_exit);
169
170MODULE_AUTHOR("Sergei Kolzun");
171MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers");
172MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index b54a9a608ac2..e635199a0cd2 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1157,6 +1157,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1157 1157
1158 if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) 1158 if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
1159 connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); 1159 connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
1160 if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE)
1161 connect_mask |= HID_CONNECT_HIDINPUT_FORCE;
1160 if (hdev->bus != BUS_USB) 1162 if (hdev->bus != BUS_USB)
1161 connect_mask &= ~HID_CONNECT_HIDDEV; 1163 connect_mask &= ~HID_CONNECT_HIDDEV;
1162 if (hid_hiddev(hdev)) 1164 if (hid_hiddev(hdev))
@@ -1239,6 +1241,9 @@ static const struct hid_device_id hid_blacklist[] = {
1239 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, 1241 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
1240 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1242 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
1241 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, 1243 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
1244#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE)
1245 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
1246#endif
1242 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, 1247 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
1243 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, 1248 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
1244 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, 1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
@@ -1294,6 +1299,7 @@ static const struct hid_device_id hid_blacklist[] = {
1294 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, 1299 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
1295 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, 1300 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
1296 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, 1301 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
1302 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
1297 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, 1303 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
1298 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, 1304 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
1299 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, 1305 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1375,10 +1381,10 @@ static const struct hid_device_id hid_blacklist[] = {
1375 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, 1381 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
1376 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, 1382 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
1377 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 1383 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1384 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
1378 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, 1385 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
1379 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1386 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1380 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 1387 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1381 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
1382 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1388 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1383 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1389 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1384 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, 1390 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
new file mode 100644
index 000000000000..7a40878f46b4
--- /dev/null
+++ b/drivers/hid/hid-elecom.c
@@ -0,0 +1,57 @@
1/*
2 * HID driver for Elecom BM084 (bluetooth mouse).
3 * Removes a non-existing horizontal wheel from
4 * the HID descriptor.
5 * (This module is based on "hid-ortek".)
6 *
7 * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 */
16
17#include <linux/device.h>
18#include <linux/hid.h>
19#include <linux/module.h>
20
21#include "hid-ids.h"
22
23static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
24 unsigned int rsize)
25{
26 if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
27 dev_info(&hdev->dev, "Fixing up Elecom BM084 "
28 "report descriptor.\n");
29 rdesc[47] = 0x00;
30 }
31}
32
33static const struct hid_device_id elecom_devices[] = {
34 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)},
35 { }
36};
37MODULE_DEVICE_TABLE(hid, elecom_devices);
38
39static struct hid_driver elecom_driver = {
40 .name = "elecom",
41 .id_table = elecom_devices,
42 .report_fixup = elecom_report_fixup
43};
44
45static int __init elecom_init(void)
46{
47 return hid_register_driver(&elecom_driver);
48}
49
50static void __exit elecom_exit(void)
51{
52 hid_unregister_driver(&elecom_driver);
53}
54
55module_init(elecom_init);
56module_exit(elecom_exit);
57MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 8aee2577c1ad..d3fc13ae094d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -34,6 +34,8 @@
34#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 34#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
35#define USB_DEVICE_ID_ACECAD_302 0x0008 35#define USB_DEVICE_ID_ACECAD_302 0x0008
36 36
37#define USB_VENDOR_ID_ACRUX 0x1a34
38
37#define USB_VENDOR_ID_ADS_TECH 0x06e1 39#define USB_VENDOR_ID_ADS_TECH 0x06e1
38#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 40#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
39 41
@@ -81,12 +83,12 @@
81#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 83#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
82#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 84#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
83#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 85#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
84#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 86#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
85#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a 87#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
86#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b 88#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
87#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c 89#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
88#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d 90#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
89#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e 91#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
90#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 92#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
91#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 93#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
92#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 94#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
@@ -118,8 +120,8 @@
118#define USB_VENDOR_ID_AVERMEDIA 0x07ca 120#define USB_VENDOR_ID_AVERMEDIA 0x07ca
119#define USB_DEVICE_ID_AVER_FM_MR800 0xb800 121#define USB_DEVICE_ID_AVER_FM_MR800 0xb800
120 122
121#define USB_VENDOR_ID_BELKIN 0x050d 123#define USB_VENDOR_ID_BELKIN 0x050d
122#define USB_DEVICE_ID_FLIP_KVM 0x3201 124#define USB_DEVICE_ID_FLIP_KVM 0x3201
123 125
124#define USB_VENDOR_ID_BERKSHIRE 0x0c98 126#define USB_VENDOR_ID_BERKSHIRE 0x0c98
125#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 127#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
@@ -128,7 +130,7 @@
128#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 130#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
129 131
130#define USB_VENDOR_ID_CANDO 0x2087 132#define USB_VENDOR_ID_CANDO 0x2087
131#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 133#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
132#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 134#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03
133 135
134#define USB_VENDOR_ID_CH 0x068e 136#define USB_VENDOR_ID_CH 0x068e
@@ -175,7 +177,7 @@
175#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a 177#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
176 178
177#define USB_VENDOR_ID_DELORME 0x1163 179#define USB_VENDOR_ID_DELORME 0x1163
178#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 180#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
179#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 181#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
180 182
181#define USB_VENDOR_ID_DMI 0x0c0b 183#define USB_VENDOR_ID_DMI 0x0c0b
@@ -187,20 +189,23 @@
187#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 189#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
188#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d 190#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
189 191
192#define USB_VENDOR_ID_ELECOM 0x056e
193#define USB_DEVICE_ID_ELECOM_BM084 0x0061
194
190#define USB_VENDOR_ID_ELO 0x04E7 195#define USB_VENDOR_ID_ELO 0x04E7
191#define USB_DEVICE_ID_ELO_TS2700 0x0020 196#define USB_DEVICE_ID_ELO_TS2700 0x0020
192 197
193#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 198#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
194#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 199#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
195 200
196#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
197#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
198
199#define USB_VENDOR_ID_ETT 0x0664 201#define USB_VENDOR_ID_ETT 0x0664
200#define USB_DEVICE_ID_TC5UH 0x0309 202#define USB_DEVICE_ID_TC5UH 0x0309
201#define USB_DEVICE_ID_TC4UM 0x0306 203#define USB_DEVICE_ID_TC4UM 0x0306
202 204
203#define USB_VENDOR_ID_EZKEY 0x0518 205#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
206#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
207
208#define USB_VENDOR_ID_EZKEY 0x0518
204#define USB_DEVICE_ID_BTC_8193 0x0002 209#define USB_DEVICE_ID_BTC_8193 0x0002
205 210
206#define USB_VENDOR_ID_GAMERON 0x0810 211#define USB_VENDOR_ID_GAMERON 0x0810
@@ -297,9 +302,16 @@
297#define USB_VENDOR_ID_KBGEAR 0x084e 302#define USB_VENDOR_ID_KBGEAR 0x084e
298#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 303#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
299 304
305#define USB_VENDOR_ID_KENSINGTON 0x047d
306#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
307
300#define USB_VENDOR_ID_KWORLD 0x1b80 308#define USB_VENDOR_ID_KWORLD 0x1b80
301#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 309#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
302 310
311#define USB_VENDOR_ID_KYE 0x0458
312#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
313#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
314
303#define USB_VENDOR_ID_LABTEC 0x1020 315#define USB_VENDOR_ID_LABTEC 0x1020
304#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 316#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
305 317
@@ -319,9 +331,6 @@
319#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 331#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
320#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 332#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
321 333
322#define USB_VENDOR_ID_KENSINGTON 0x047d
323#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
324
325#define USB_VENDOR_ID_LOGITECH 0x046d 334#define USB_VENDOR_ID_LOGITECH 0x046d
326#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 335#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
327#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 336#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -377,23 +386,23 @@
377#define USB_VENDOR_ID_MONTEREY 0x0566 386#define USB_VENDOR_ID_MONTEREY 0x0566
378#define USB_DEVICE_ID_GENIUS_KB29E 0x3004 387#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
379 388
389#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
390#define USB_DEVICE_ID_N_S_HARMONY 0xc359
391
392#define USB_VENDOR_ID_NATSU 0x08b7
393#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
394
380#define USB_VENDOR_ID_NCR 0x0404 395#define USB_VENDOR_ID_NCR 0x0404
381#define USB_DEVICE_ID_NCR_FIRST 0x0300 396#define USB_DEVICE_ID_NCR_FIRST 0x0300
382#define USB_DEVICE_ID_NCR_LAST 0x03ff 397#define USB_DEVICE_ID_NCR_LAST 0x03ff
383 398
384#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
385#define USB_DEVICE_ID_N_S_HARMONY 0xc359
386
387#define USB_VENDOR_ID_NATSU 0x08b7
388#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
389
390#define USB_VENDOR_ID_NEC 0x073e 399#define USB_VENDOR_ID_NEC 0x073e
391#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 400#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
392 401
393#define USB_VENDOR_ID_NEXTWINDOW 0x1926 402#define USB_VENDOR_ID_NEXTWINDOW 0x1926
394#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 403#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
395 404
396#define USB_VENDOR_ID_NTRIG 0x1b96 405#define USB_VENDOR_ID_NTRIG 0x1b96
397#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 406#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
398#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 407#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
399#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 408#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004
@@ -428,9 +437,12 @@
428#define USB_VENDOR_ID_PETALYNX 0x18b1 437#define USB_VENDOR_ID_PETALYNX 0x18b1
429#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 438#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
430 439
431#define USB_VENDOR_ID_PHILIPS 0x0471 440#define USB_VENDOR_ID_PHILIPS 0x0471
432#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 441#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
433 442
443#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3
444#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
445
434#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 446#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
435#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 447#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
436 448
@@ -440,16 +452,16 @@
440#define USB_VENDOR_ID_PRODIGE 0x05af 452#define USB_VENDOR_ID_PRODIGE 0x05af
441#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 453#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
442 454
455#define USB_VENDOR_ID_QUANTA 0x0408
456#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
457#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
458
443#define USB_VENDOR_ID_ROCCAT 0x1e7d 459#define USB_VENDOR_ID_ROCCAT 0x1e7d
444#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 460#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
445 461
446#define USB_VENDOR_ID_SAITEK 0x06a3 462#define USB_VENDOR_ID_SAITEK 0x06a3
447#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 463#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
448 464
449#define USB_VENDOR_ID_QUANTA 0x0408
450#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
451#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
452
453#define USB_VENDOR_ID_SAMSUNG 0x0419 465#define USB_VENDOR_ID_SAMSUNG 0x0419
454#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 466#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
455#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 467#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
@@ -473,20 +485,23 @@
473 485
474#define USB_VENDOR_ID_THRUSTMASTER 0x044f 486#define USB_VENDOR_ID_THRUSTMASTER 0x044f
475 487
476#define USB_VENDOR_ID_TOUCHPACK 0x1bfd 488#define USB_VENDOR_ID_TOPSEED 0x0766
477#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 489#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
490
491#define USB_VENDOR_ID_TOPSEED2 0x1784
492#define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004
478 493
479#define USB_VENDOR_ID_TOPMAX 0x0663 494#define USB_VENDOR_ID_TOPMAX 0x0663
480#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 495#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
481 496
482#define USB_VENDOR_ID_TOPSEED 0x0766 497#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
483#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 498#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
484 499
485#define USB_VENDOR_ID_TURBOX 0x062a 500#define USB_VENDOR_ID_TURBOX 0x062a
486#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 501#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
487 502
488#define USB_VENDOR_ID_TWINHAN 0x6253 503#define USB_VENDOR_ID_TWINHAN 0x6253
489#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 504#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
490 505
491#define USB_VENDOR_ID_UCLOGIC 0x5543 506#define USB_VENDOR_ID_UCLOGIC 0x5543
492#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 507#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
@@ -501,7 +516,6 @@
501 516
502#define USB_VENDOR_ID_WACOM 0x056a 517#define USB_VENDOR_ID_WACOM 0x056a
503#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 518#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
504#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0xbd
505 519
506#define USB_VENDOR_ID_WISEGROUP 0x0925 520#define USB_VENDOR_ID_WISEGROUP 0x0925
507#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 521#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
@@ -523,9 +537,4 @@
523#define USB_VENDOR_ID_ZYDACRON 0x13EC 537#define USB_VENDOR_ID_ZYDACRON 0x13EC
524#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 538#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
525 539
526#define USB_VENDOR_ID_KYE 0x0458
527#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
528#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
529
530
531#endif 540#endif
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 69d152e16a6a..6c03dcc5760a 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -199,11 +199,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
199 case HID_GD_MOUSE: 199 case HID_GD_MOUSE:
200 case HID_GD_POINTER: code += 0x110; break; 200 case HID_GD_POINTER: code += 0x110; break;
201 case HID_GD_JOYSTICK: 201 case HID_GD_JOYSTICK:
202 if (code <= 0xf) 202 if (code <= 0xf)
203 code += BTN_JOYSTICK; 203 code += BTN_JOYSTICK;
204 else 204 else
205 code += BTN_TRIGGER_HAPPY; 205 code += BTN_TRIGGER_HAPPY;
206 break; 206 break;
207 case HID_GD_GAMEPAD: code += 0x130; break; 207 case HID_GD_GAMEPAD: code += 0x130; break;
208 default: 208 default:
209 switch (field->physical) { 209 switch (field->physical) {
@@ -301,6 +301,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
301 301
302 case HID_UP_DIGITIZER: 302 case HID_UP_DIGITIZER:
303 switch (usage->hid & 0xff) { 303 switch (usage->hid & 0xff) {
304 case 0x00: /* Undefined */
305 goto ignore;
306
304 case 0x30: /* TipPressure */ 307 case 0x30: /* TipPressure */
305 if (!test_bit(BTN_TOUCH, input->keybit)) { 308 if (!test_bit(BTN_TOUCH, input->keybit)) {
306 device->quirks |= HID_QUIRK_NOTOUCH; 309 device->quirks |= HID_QUIRK_NOTOUCH;
@@ -480,7 +483,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
480 483
481 case HID_UP_LOGIVENDOR: 484 case HID_UP_LOGIVENDOR:
482 goto ignore; 485 goto ignore;
483 486
484 case HID_UP_PID: 487 case HID_UP_PID:
485 switch (usage->hid & HID_USAGE) { 488 switch (usage->hid & HID_USAGE) {
486 case 0xa4: map_key_clear(BTN_DEAD); break; 489 case 0xa4: map_key_clear(BTN_DEAD); break;
@@ -589,9 +592,9 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
589 hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; 592 hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
590 if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; 593 if (hat_dir < 0 || hat_dir > 8) hat_dir = 0;
591 input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); 594 input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x);
592 input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); 595 input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y);
593 return; 596 return;
594 } 597 }
595 598
596 if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ 599 if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
597 *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); 600 *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index f10d56a15f21..319b0e57ee41 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -30,6 +30,21 @@ static bool emulate_scroll_wheel = true;
30module_param(emulate_scroll_wheel, bool, 0644); 30module_param(emulate_scroll_wheel, bool, 0644);
31MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); 31MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
32 32
33static unsigned int scroll_speed = 32;
34static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
35 unsigned long speed;
36 if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
37 return -EINVAL;
38 scroll_speed = speed;
39 return 0;
40}
41module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644);
42MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)");
43
44static bool scroll_acceleration = false;
45module_param(scroll_acceleration, bool, 0644);
46MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
47
33static bool report_touches = true; 48static bool report_touches = true;
34module_param(report_touches, bool, 0644); 49module_param(report_touches, bool, 0644);
35MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); 50MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
@@ -50,6 +65,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
50#define TOUCH_STATE_START 0x30 65#define TOUCH_STATE_START 0x30
51#define TOUCH_STATE_DRAG 0x40 66#define TOUCH_STATE_DRAG 0x40
52 67
68#define SCROLL_ACCEL_DEFAULT 7
69
53/** 70/**
54 * struct magicmouse_sc - Tracks Magic Mouse-specific data. 71 * struct magicmouse_sc - Tracks Magic Mouse-specific data.
55 * @input: Input device through which we report events. 72 * @input: Input device through which we report events.
@@ -78,8 +95,10 @@ struct magicmouse_sc {
78 struct { 95 struct {
79 short x; 96 short x;
80 short y; 97 short y;
98 short scroll_x;
81 short scroll_y; 99 short scroll_y;
82 u8 size; 100 u8 size;
101 u8 down;
83 } touches[16]; 102 } touches[16];
84 int tracking_ids[16]; 103 int tracking_ids[16];
85}; 104};
@@ -141,7 +160,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
141 input_report_key(msc->input, BTN_RIGHT, state & 2); 160 input_report_key(msc->input, BTN_RIGHT, state & 2);
142 161
143 if (state != last_state) 162 if (state != last_state)
144 msc->scroll_accel = 0; 163 msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
145} 164}
146 165
147static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) 166static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
@@ -152,6 +171,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
152 int id = (misc >> 6) & 15; 171 int id = (misc >> 6) & 15;
153 int x = x_y << 12 >> 20; 172 int x = x_y << 12 >> 20;
154 int y = -(x_y >> 20); 173 int y = -(x_y >> 20);
174 int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE;
155 175
156 /* Store tracking ID and other fields. */ 176 /* Store tracking ID and other fields. */
157 msc->tracking_ids[raw_id] = id; 177 msc->tracking_ids[raw_id] = id;
@@ -160,42 +180,54 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
160 msc->touches[id].size = misc & 63; 180 msc->touches[id].size = misc & 63;
161 181
162 /* If requested, emulate a scroll wheel by detecting small 182 /* If requested, emulate a scroll wheel by detecting small
163 * vertical touch motions along the middle of the mouse. 183 * vertical touch motions.
164 */ 184 */
165 if (emulate_scroll_wheel && 185 if (emulate_scroll_wheel) {
166 middle_button_start < x && x < middle_button_stop) {
167 static const int accel_profile[] = {
168 256, 228, 192, 160, 128, 96, 64, 32,
169 };
170 unsigned long now = jiffies; 186 unsigned long now = jiffies;
171 int step = msc->touches[id].scroll_y - y; 187 int step_x = msc->touches[id].scroll_x - x;
172 188 int step_y = msc->touches[id].scroll_y - y;
173 /* Reset acceleration after half a second. */
174 if (time_after(now, msc->scroll_jiffies + HZ / 2))
175 msc->scroll_accel = 0;
176 189
177 /* Calculate and apply the scroll motion. */ 190 /* Calculate and apply the scroll motion. */
178 switch (tdata[7] & TOUCH_STATE_MASK) { 191 switch (tdata[7] & TOUCH_STATE_MASK) {
179 case TOUCH_STATE_START: 192 case TOUCH_STATE_START:
193 msc->touches[id].scroll_x = x;
180 msc->touches[id].scroll_y = y; 194 msc->touches[id].scroll_y = y;
181 msc->scroll_accel = min_t(int, msc->scroll_accel + 1, 195
182 ARRAY_SIZE(accel_profile) - 1); 196 /* Reset acceleration after half a second. */
197 if (scroll_acceleration && time_before(now,
198 msc->scroll_jiffies + HZ / 2))
199 msc->scroll_accel = max_t(int,
200 msc->scroll_accel - 1, 1);
201 else
202 msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
203
183 break; 204 break;
184 case TOUCH_STATE_DRAG: 205 case TOUCH_STATE_DRAG:
185 step = step / accel_profile[msc->scroll_accel]; 206 step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
186 if (step != 0) { 207 if (step_x != 0) {
187 msc->touches[id].scroll_y = y; 208 msc->touches[id].scroll_x -= step_x *
209 (64 - scroll_speed) * msc->scroll_accel;
188 msc->scroll_jiffies = now; 210 msc->scroll_jiffies = now;
189 input_report_rel(input, REL_WHEEL, step); 211 input_report_rel(input, REL_HWHEEL, -step_x);
212 }
213
214 step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
215 if (step_y != 0) {
216 msc->touches[id].scroll_y -= step_y *
217 (64 - scroll_speed) * msc->scroll_accel;
218 msc->scroll_jiffies = now;
219 input_report_rel(input, REL_WHEEL, step_y);
190 } 220 }
191 break; 221 break;
192 } 222 }
193 } 223 }
194 224
195 /* Generate the input events for this touch. */ 225 /* Generate the input events for this touch. */
196 if (report_touches) { 226 if (report_touches && down) {
197 int orientation = (misc >> 10) - 32; 227 int orientation = (misc >> 10) - 32;
198 228
229 msc->touches[id].down = 1;
230
199 input_report_abs(input, ABS_MT_TRACKING_ID, id); 231 input_report_abs(input, ABS_MT_TRACKING_ID, id);
200 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); 232 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
201 input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); 233 input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]);
@@ -215,7 +247,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
215{ 247{
216 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 248 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
217 struct input_dev *input = msc->input; 249 struct input_dev *input = msc->input;
218 int x, y, ts, ii, clicks; 250 int x, y, ts, ii, clicks, last_up;
219 251
220 switch (data[0]) { 252 switch (data[0]) {
221 case 0x10: 253 case 0x10:
@@ -235,12 +267,26 @@ static int magicmouse_raw_event(struct hid_device *hdev,
235 msc->ntouches = (size - 6) / 8; 267 msc->ntouches = (size - 6) / 8;
236 for (ii = 0; ii < msc->ntouches; ii++) 268 for (ii = 0; ii < msc->ntouches; ii++)
237 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 269 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
270
271 if (report_touches) {
272 last_up = 1;
273 for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) {
274 if (msc->touches[ii].down) {
275 last_up = 0;
276 msc->touches[ii].down = 0;
277 }
278 }
279 if (last_up) {
280 input_mt_sync(input);
281 }
282 }
283
238 /* When emulating three-button mode, it is important 284 /* When emulating three-button mode, it is important
239 * to have the current touch information before 285 * to have the current touch information before
240 * generating a click event. 286 * generating a click event.
241 */ 287 */
242 x = (signed char)data[1]; 288 x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
243 y = (signed char)data[2]; 289 y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
244 clicks = data[3]; 290 clicks = data[3];
245 break; 291 break;
246 case 0x20: /* Theoretically battery status (0-100), but I have 292 case 0x20: /* Theoretically battery status (0-100), but I have
@@ -301,8 +347,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
301 __set_bit(EV_REL, input->evbit); 347 __set_bit(EV_REL, input->evbit);
302 __set_bit(REL_X, input->relbit); 348 __set_bit(REL_X, input->relbit);
303 __set_bit(REL_Y, input->relbit); 349 __set_bit(REL_Y, input->relbit);
304 if (emulate_scroll_wheel) 350 if (emulate_scroll_wheel) {
305 __set_bit(REL_WHEEL, input->relbit); 351 __set_bit(REL_WHEEL, input->relbit);
352 __set_bit(REL_HWHEEL, input->relbit);
353 }
306 354
307 if (report_touches) { 355 if (report_touches) {
308 __set_bit(EV_ABS, input->evbit); 356 __set_bit(EV_ABS, input->evbit);
@@ -345,6 +393,8 @@ static int magicmouse_probe(struct hid_device *hdev,
345 return -ENOMEM; 393 return -ENOMEM;
346 } 394 }
347 395
396 msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
397
348 msc->quirks = id->driver_data; 398 msc->quirks = id->driver_data;
349 hid_set_drvdata(hdev, msc); 399 hid_set_drvdata(hdev, msc);
350 400
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index 7aabf65c48ef..346f0e34987e 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -127,6 +127,26 @@ static const struct fb_var_screeninfo picolcdfb_var = {
127 .height = 26, 127 .height = 26,
128 .bits_per_pixel = 1, 128 .bits_per_pixel = 1,
129 .grayscale = 1, 129 .grayscale = 1,
130 .red = {
131 .offset = 0,
132 .length = 1,
133 .msb_right = 0,
134 },
135 .green = {
136 .offset = 0,
137 .length = 1,
138 .msb_right = 0,
139 },
140 .blue = {
141 .offset = 0,
142 .length = 1,
143 .msb_right = 0,
144 },
145 .transp = {
146 .offset = 0,
147 .length = 0,
148 .msb_right = 0,
149 },
130}; 150};
131#endif /* CONFIG_HID_PICOLCD_FB */ 151#endif /* CONFIG_HID_PICOLCD_FB */
132 152
@@ -188,6 +208,7 @@ struct picolcd_data {
188 /* Framebuffer stuff */ 208 /* Framebuffer stuff */
189 u8 fb_update_rate; 209 u8 fb_update_rate;
190 u8 fb_bpp; 210 u8 fb_bpp;
211 u8 fb_force;
191 u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */ 212 u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */
192 u8 *fb_bitmap; /* framebuffer */ 213 u8 *fb_bitmap; /* framebuffer */
193 struct fb_info *fb_info; 214 struct fb_info *fb_info;
@@ -346,7 +367,7 @@ static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
346 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32; 367 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
347 for (i = 0; i < 64; i++) { 368 for (i = 0; i < 64; i++) {
348 tdata[i] <<= 1; 369 tdata[i] <<= 1;
349 tdata[i] |= (bdata[i/8] >> (7 - i % 8)) & 0x01; 370 tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01;
350 } 371 }
351 } 372 }
352 } else if (bpp == 8) { 373 } else if (bpp == 8) {
@@ -399,13 +420,10 @@ static int picolcd_fb_reset(struct picolcd_data *data, int clear)
399 420
400 if (data->fb_bitmap) { 421 if (data->fb_bitmap) {
401 if (clear) { 422 if (clear) {
402 memset(data->fb_vbitmap, 0xff, PICOLCDFB_SIZE); 423 memset(data->fb_vbitmap, 0, PICOLCDFB_SIZE);
403 memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp); 424 memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp);
404 } else {
405 /* invert 1 byte in each tile to force resend */
406 for (i = 0; i < PICOLCDFB_SIZE; i += 64)
407 data->fb_vbitmap[i] = ~data->fb_vbitmap[i];
408 } 425 }
426 data->fb_force = 1;
409 } 427 }
410 428
411 /* schedule first output of framebuffer */ 429 /* schedule first output of framebuffer */
@@ -421,6 +439,9 @@ static void picolcd_fb_update(struct picolcd_data *data)
421 int chip, tile, n; 439 int chip, tile, n;
422 unsigned long flags; 440 unsigned long flags;
423 441
442 if (!data)
443 return;
444
424 spin_lock_irqsave(&data->lock, flags); 445 spin_lock_irqsave(&data->lock, flags);
425 if (!(data->status & PICOLCD_READY_FB)) { 446 if (!(data->status & PICOLCD_READY_FB)) {
426 spin_unlock_irqrestore(&data->lock, flags); 447 spin_unlock_irqrestore(&data->lock, flags);
@@ -440,14 +461,18 @@ static void picolcd_fb_update(struct picolcd_data *data)
440 for (chip = 0; chip < 4; chip++) 461 for (chip = 0; chip < 4; chip++)
441 for (tile = 0; tile < 8; tile++) 462 for (tile = 0; tile < 8; tile++)
442 if (picolcd_fb_update_tile(data->fb_vbitmap, 463 if (picolcd_fb_update_tile(data->fb_vbitmap,
443 data->fb_bitmap, data->fb_bpp, chip, tile)) { 464 data->fb_bitmap, data->fb_bpp, chip, tile) ||
465 data->fb_force) {
444 n += 2; 466 n += 2;
467 if (!data->fb_info->par)
468 return; /* device lost! */
445 if (n >= HID_OUTPUT_FIFO_SIZE / 2) { 469 if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
446 usbhid_wait_io(data->hdev); 470 usbhid_wait_io(data->hdev);
447 n = 0; 471 n = 0;
448 } 472 }
449 picolcd_fb_send_tile(data->hdev, chip, tile); 473 picolcd_fb_send_tile(data->hdev, chip, tile);
450 } 474 }
475 data->fb_force = false;
451 if (n) 476 if (n)
452 usbhid_wait_io(data->hdev); 477 usbhid_wait_io(data->hdev);
453} 478}
@@ -511,11 +536,23 @@ static int picolcd_fb_blank(int blank, struct fb_info *info)
511static void picolcd_fb_destroy(struct fb_info *info) 536static void picolcd_fb_destroy(struct fb_info *info)
512{ 537{
513 struct picolcd_data *data = info->par; 538 struct picolcd_data *data = info->par;
539 u32 *ref_cnt = info->pseudo_palette;
540 int may_release;
541
514 info->par = NULL; 542 info->par = NULL;
515 if (data) 543 if (data)
516 data->fb_info = NULL; 544 data->fb_info = NULL;
517 fb_deferred_io_cleanup(info); 545 fb_deferred_io_cleanup(info);
518 framebuffer_release(info); 546
547 ref_cnt--;
548 mutex_lock(&info->lock);
549 (*ref_cnt)--;
550 may_release = !ref_cnt;
551 mutex_unlock(&info->lock);
552 if (may_release) {
553 framebuffer_release(info);
554 vfree((u8 *)info->fix.smem_start);
555 }
519} 556}
520 557
521static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 558static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -526,29 +563,37 @@ static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *i
526 /* only allow 1/8 bit depth (8-bit is grayscale) */ 563 /* only allow 1/8 bit depth (8-bit is grayscale) */
527 *var = picolcdfb_var; 564 *var = picolcdfb_var;
528 var->activate = activate; 565 var->activate = activate;
529 if (bpp >= 8) 566 if (bpp >= 8) {
530 var->bits_per_pixel = 8; 567 var->bits_per_pixel = 8;
531 else 568 var->red.length = 8;
569 var->green.length = 8;
570 var->blue.length = 8;
571 } else {
532 var->bits_per_pixel = 1; 572 var->bits_per_pixel = 1;
573 var->red.length = 1;
574 var->green.length = 1;
575 var->blue.length = 1;
576 }
533 return 0; 577 return 0;
534} 578}
535 579
536static int picolcd_set_par(struct fb_info *info) 580static int picolcd_set_par(struct fb_info *info)
537{ 581{
538 struct picolcd_data *data = info->par; 582 struct picolcd_data *data = info->par;
539 u8 *o_fb, *n_fb; 583 u8 *tmp_fb, *o_fb;
584 if (!data)
585 return -ENODEV;
540 if (info->var.bits_per_pixel == data->fb_bpp) 586 if (info->var.bits_per_pixel == data->fb_bpp)
541 return 0; 587 return 0;
542 /* switch between 1/8 bit depths */ 588 /* switch between 1/8 bit depths */
543 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8) 589 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
544 return -EINVAL; 590 return -EINVAL;
545 591
546 o_fb = data->fb_bitmap; 592 o_fb = data->fb_bitmap;
547 n_fb = vmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel); 593 tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL);
548 if (!n_fb) 594 if (!tmp_fb)
549 return -ENOMEM; 595 return -ENOMEM;
550 596
551 fb_deferred_io_cleanup(info);
552 /* translate FB content to new bits-per-pixel */ 597 /* translate FB content to new bits-per-pixel */
553 if (info->var.bits_per_pixel == 1) { 598 if (info->var.bits_per_pixel == 1) {
554 int i, b; 599 int i, b;
@@ -558,24 +603,87 @@ static int picolcd_set_par(struct fb_info *info)
558 p <<= 1; 603 p <<= 1;
559 p |= o_fb[i*8+b] ? 0x01 : 0x00; 604 p |= o_fb[i*8+b] ? 0x01 : 0x00;
560 } 605 }
606 tmp_fb[i] = p;
561 } 607 }
608 memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
562 info->fix.visual = FB_VISUAL_MONO01; 609 info->fix.visual = FB_VISUAL_MONO01;
563 info->fix.line_length = PICOLCDFB_WIDTH / 8; 610 info->fix.line_length = PICOLCDFB_WIDTH / 8;
564 } else { 611 } else {
565 int i; 612 int i;
613 memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
566 for (i = 0; i < PICOLCDFB_SIZE * 8; i++) 614 for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
567 n_fb[i] = o_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00; 615 o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
568 info->fix.visual = FB_VISUAL_TRUECOLOR; 616 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
569 info->fix.line_length = PICOLCDFB_WIDTH; 617 info->fix.line_length = PICOLCDFB_WIDTH;
570 } 618 }
571 619
572 data->fb_bitmap = n_fb; 620 kfree(tmp_fb);
573 data->fb_bpp = info->var.bits_per_pixel; 621 data->fb_bpp = info->var.bits_per_pixel;
574 info->screen_base = (char __force __iomem *)n_fb; 622 return 0;
575 info->fix.smem_start = (unsigned long)n_fb; 623}
576 info->fix.smem_len = PICOLCDFB_SIZE*data->fb_bpp; 624
577 fb_deferred_io_init(info); 625/* Do refcounting on our FB and cleanup per worker if FB is
578 vfree(o_fb); 626 * closed after unplug of our device
627 * (fb_release holds info->lock and still touches info after
628 * we return so we can't release it immediately.
629 */
630struct picolcd_fb_cleanup_item {
631 struct fb_info *info;
632 struct picolcd_fb_cleanup_item *next;
633};
634static struct picolcd_fb_cleanup_item *fb_pending;
635DEFINE_SPINLOCK(fb_pending_lock);
636
637static void picolcd_fb_do_cleanup(struct work_struct *data)
638{
639 struct picolcd_fb_cleanup_item *item;
640 unsigned long flags;
641
642 do {
643 spin_lock_irqsave(&fb_pending_lock, flags);
644 item = fb_pending;
645 fb_pending = item ? item->next : NULL;
646 spin_unlock_irqrestore(&fb_pending_lock, flags);
647
648 if (item) {
649 u8 *fb = (u8 *)item->info->fix.smem_start;
650 /* make sure we do not race against fb core when
651 * releasing */
652 mutex_lock(&item->info->lock);
653 mutex_unlock(&item->info->lock);
654 framebuffer_release(item->info);
655 vfree(fb);
656 }
657 } while (item);
658}
659
660DECLARE_WORK(picolcd_fb_cleanup, picolcd_fb_do_cleanup);
661
662static int picolcd_fb_open(struct fb_info *info, int u)
663{
664 u32 *ref_cnt = info->pseudo_palette;
665 ref_cnt--;
666
667 (*ref_cnt)++;
668 return 0;
669}
670
671static int picolcd_fb_release(struct fb_info *info, int u)
672{
673 u32 *ref_cnt = info->pseudo_palette;
674 ref_cnt--;
675
676 (*ref_cnt)++;
677 if (!*ref_cnt) {
678 unsigned long flags;
679 struct picolcd_fb_cleanup_item *item = (struct picolcd_fb_cleanup_item *)ref_cnt;
680 item--;
681 spin_lock_irqsave(&fb_pending_lock, flags);
682 item->next = fb_pending;
683 fb_pending = item;
684 spin_unlock_irqrestore(&fb_pending_lock, flags);
685 schedule_work(&picolcd_fb_cleanup);
686 }
579 return 0; 687 return 0;
580} 688}
581 689
@@ -583,6 +691,8 @@ static int picolcd_set_par(struct fb_info *info)
583static struct fb_ops picolcdfb_ops = { 691static struct fb_ops picolcdfb_ops = {
584 .owner = THIS_MODULE, 692 .owner = THIS_MODULE,
585 .fb_destroy = picolcd_fb_destroy, 693 .fb_destroy = picolcd_fb_destroy,
694 .fb_open = picolcd_fb_open,
695 .fb_release = picolcd_fb_release,
586 .fb_read = fb_sys_read, 696 .fb_read = fb_sys_read,
587 .fb_write = picolcd_fb_write, 697 .fb_write = picolcd_fb_write,
588 .fb_blank = picolcd_fb_blank, 698 .fb_blank = picolcd_fb_blank,
@@ -660,11 +770,12 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
660{ 770{
661 struct device *dev = &data->hdev->dev; 771 struct device *dev = &data->hdev->dev;
662 struct fb_info *info = NULL; 772 struct fb_info *info = NULL;
663 int error = -ENOMEM; 773 int i, error = -ENOMEM;
664 u8 *fb_vbitmap = NULL; 774 u8 *fb_vbitmap = NULL;
665 u8 *fb_bitmap = NULL; 775 u8 *fb_bitmap = NULL;
776 u32 *palette;
666 777
667 fb_bitmap = vmalloc(PICOLCDFB_SIZE*picolcdfb_var.bits_per_pixel); 778 fb_bitmap = vmalloc(PICOLCDFB_SIZE*8);
668 if (fb_bitmap == NULL) { 779 if (fb_bitmap == NULL) {
669 dev_err(dev, "can't get a free page for framebuffer\n"); 780 dev_err(dev, "can't get a free page for framebuffer\n");
670 goto err_nomem; 781 goto err_nomem;
@@ -678,18 +789,29 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
678 789
679 data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT; 790 data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
680 data->fb_defio = picolcd_fb_defio; 791 data->fb_defio = picolcd_fb_defio;
681 info = framebuffer_alloc(0, dev); 792 /* The extra memory is:
793 * - struct picolcd_fb_cleanup_item
794 * - u32 for ref_count
795 * - 256*u32 for pseudo_palette
796 */
797 info = framebuffer_alloc(257 * sizeof(u32) + sizeof(struct picolcd_fb_cleanup_item), dev);
682 if (info == NULL) { 798 if (info == NULL) {
683 dev_err(dev, "failed to allocate a framebuffer\n"); 799 dev_err(dev, "failed to allocate a framebuffer\n");
684 goto err_nomem; 800 goto err_nomem;
685 } 801 }
686 802
803 palette = info->par + sizeof(struct picolcd_fb_cleanup_item);
804 *palette = 1;
805 palette++;
806 for (i = 0; i < 256; i++)
807 palette[i] = i > 0 && i < 16 ? 0xff : 0;
808 info->pseudo_palette = palette;
687 info->fbdefio = &data->fb_defio; 809 info->fbdefio = &data->fb_defio;
688 info->screen_base = (char __force __iomem *)fb_bitmap; 810 info->screen_base = (char __force __iomem *)fb_bitmap;
689 info->fbops = &picolcdfb_ops; 811 info->fbops = &picolcdfb_ops;
690 info->var = picolcdfb_var; 812 info->var = picolcdfb_var;
691 info->fix = picolcdfb_fix; 813 info->fix = picolcdfb_fix;
692 info->fix.smem_len = PICOLCDFB_SIZE; 814 info->fix.smem_len = PICOLCDFB_SIZE*8;
693 info->fix.smem_start = (unsigned long)fb_bitmap; 815 info->fix.smem_start = (unsigned long)fb_bitmap;
694 info->par = data; 816 info->par = data;
695 info->flags = FBINFO_FLAG_DEFAULT; 817 info->flags = FBINFO_FLAG_DEFAULT;
@@ -707,18 +829,20 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
707 dev_err(dev, "failed to create sysfs attributes\n"); 829 dev_err(dev, "failed to create sysfs attributes\n");
708 goto err_cleanup; 830 goto err_cleanup;
709 } 831 }
832 fb_deferred_io_init(info);
710 data->fb_info = info; 833 data->fb_info = info;
711 error = register_framebuffer(info); 834 error = register_framebuffer(info);
712 if (error) { 835 if (error) {
713 dev_err(dev, "failed to register framebuffer\n"); 836 dev_err(dev, "failed to register framebuffer\n");
714 goto err_sysfs; 837 goto err_sysfs;
715 } 838 }
716 fb_deferred_io_init(info);
717 /* schedule first output of framebuffer */ 839 /* schedule first output of framebuffer */
840 data->fb_force = 1;
718 schedule_delayed_work(&info->deferred_work, 0); 841 schedule_delayed_work(&info->deferred_work, 0);
719 return 0; 842 return 0;
720 843
721err_sysfs: 844err_sysfs:
845 fb_deferred_io_cleanup(info);
722 device_remove_file(dev, &dev_attr_fb_update_rate); 846 device_remove_file(dev, &dev_attr_fb_update_rate);
723err_cleanup: 847err_cleanup:
724 data->fb_vbitmap = NULL; 848 data->fb_vbitmap = NULL;
@@ -737,19 +861,17 @@ static void picolcd_exit_framebuffer(struct picolcd_data *data)
737{ 861{
738 struct fb_info *info = data->fb_info; 862 struct fb_info *info = data->fb_info;
739 u8 *fb_vbitmap = data->fb_vbitmap; 863 u8 *fb_vbitmap = data->fb_vbitmap;
740 u8 *fb_bitmap = data->fb_bitmap;
741 864
742 if (!info) 865 if (!info)
743 return; 866 return;
744 867
868 info->par = NULL;
869 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
870 unregister_framebuffer(info);
745 data->fb_vbitmap = NULL; 871 data->fb_vbitmap = NULL;
746 data->fb_bitmap = NULL; 872 data->fb_bitmap = NULL;
747 data->fb_bpp = 0; 873 data->fb_bpp = 0;
748 data->fb_info = NULL; 874 data->fb_info = NULL;
749 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
750 fb_deferred_io_cleanup(info);
751 unregister_framebuffer(info);
752 vfree(fb_bitmap);
753 kfree(fb_vbitmap); 875 kfree(fb_vbitmap);
754} 876}
755 877
@@ -2566,6 +2688,13 @@ static void picolcd_remove(struct hid_device *hdev)
2566 spin_lock_irqsave(&data->lock, flags); 2688 spin_lock_irqsave(&data->lock, flags);
2567 data->status |= PICOLCD_FAILED; 2689 data->status |= PICOLCD_FAILED;
2568 spin_unlock_irqrestore(&data->lock, flags); 2690 spin_unlock_irqrestore(&data->lock, flags);
2691#ifdef CONFIG_HID_PICOLCD_FB
2692 /* short-circuit FB as early as possible in order to
2693 * avoid long delays if we host console.
2694 */
2695 if (data->fb_info)
2696 data->fb_info->par = NULL;
2697#endif
2569 2698
2570 picolcd_exit_devfs(data); 2699 picolcd_exit_devfs(data);
2571 device_remove_file(&hdev->dev, &dev_attr_operation_mode); 2700 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
@@ -2623,6 +2752,10 @@ static int __init picolcd_init(void)
2623static void __exit picolcd_exit(void) 2752static void __exit picolcd_exit(void)
2624{ 2753{
2625 hid_unregister_driver(&picolcd_driver); 2754 hid_unregister_driver(&picolcd_driver);
2755#ifdef CONFIG_HID_PICOLCD_FB
2756 flush_scheduled_work();
2757 WARN_ON(fb_pending);
2758#endif
2626} 2759}
2627 2760
2628module_init(picolcd_init); 2761module_init(picolcd_init);
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index 17f2dc04f883..f77695762cb5 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -22,11 +22,6 @@
22 * Is it possible to remove and reinstall the urb in raw-event- or any 22 * Is it possible to remove and reinstall the urb in raw-event- or any
23 * other handler, or to defer this action to be executed somewhere else? 23 * other handler, or to defer this action to be executed somewhere else?
24 * 24 *
25 * TODO implement notification mechanism for overlong macro execution
26 * If user wants to execute an overlong macro only the names of macroset
27 * and macro are given. Should userland tap hidraw or is there an
28 * additional streaming mechanism?
29 *
30 * TODO is it possible to overwrite group for sysfs attributes via udev? 25 * TODO is it possible to overwrite group for sysfs attributes via udev?
31 */ 26 */
32 27
@@ -277,7 +272,7 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
277 count = sizeof(struct kone_settings) - off; 272 count = sizeof(struct kone_settings) - off;
278 273
279 mutex_lock(&kone->kone_lock); 274 mutex_lock(&kone->kone_lock);
280 memcpy(buf, &kone->settings + off, count); 275 memcpy(buf, ((char const *)&kone->settings) + off, count);
281 mutex_unlock(&kone->kone_lock); 276 mutex_unlock(&kone->kone_lock);
282 277
283 return count; 278 return count;
@@ -337,7 +332,7 @@ static ssize_t kone_sysfs_read_profilex(struct kobject *kobj,
337 count = sizeof(struct kone_profile) - off; 332 count = sizeof(struct kone_profile) - off;
338 333
339 mutex_lock(&kone->kone_lock); 334 mutex_lock(&kone->kone_lock);
340 memcpy(buf, &kone->profiles[number - 1], sizeof(struct kone_profile)); 335 memcpy(buf, ((char const *)&kone->profiles[number - 1]) + off, count);
341 mutex_unlock(&kone->kone_lock); 336 mutex_unlock(&kone->kone_lock);
342 337
343 return count; 338 return count;
@@ -623,18 +618,6 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
623} 618}
624 619
625/* 620/*
626 * This file is used by userland software to find devices that are handled by
627 * this driver. This provides a consistent way for actual and older kernels
628 * where this driver replaced usbhid instead of generic-usb.
629 * Driver capabilities are determined by version number.
630 */
631static ssize_t kone_sysfs_show_driver_version(struct device *dev,
632 struct device_attribute *attr, char *buf)
633{
634 return snprintf(buf, PAGE_SIZE, ROCCAT_KONE_DRIVER_VERSION "\n");
635}
636
637/*
638 * Read actual dpi settings. 621 * Read actual dpi settings.
639 * Returns raw value for further processing. Refer to enum kone_polling_rates to 622 * Returns raw value for further processing. Refer to enum kone_polling_rates to
640 * get real value. 623 * get real value.
@@ -671,9 +654,6 @@ static DEVICE_ATTR(startup_profile, 0660,
671 kone_sysfs_show_startup_profile, 654 kone_sysfs_show_startup_profile,
672 kone_sysfs_set_startup_profile); 655 kone_sysfs_set_startup_profile);
673 656
674static DEVICE_ATTR(kone_driver_version, 0440,
675 kone_sysfs_show_driver_version, NULL);
676
677static struct attribute *kone_attributes[] = { 657static struct attribute *kone_attributes[] = {
678 &dev_attr_actual_dpi.attr, 658 &dev_attr_actual_dpi.attr,
679 &dev_attr_actual_profile.attr, 659 &dev_attr_actual_profile.attr,
@@ -681,7 +661,6 @@ static struct attribute *kone_attributes[] = {
681 &dev_attr_firmware_version.attr, 661 &dev_attr_firmware_version.attr,
682 &dev_attr_tcu.attr, 662 &dev_attr_tcu.attr,
683 &dev_attr_startup_profile.attr, 663 &dev_attr_startup_profile.attr,
684 &dev_attr_kone_driver_version.attr,
685 NULL 664 NULL
686}; 665};
687 666
diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h
index 003e6f81c195..130d6566ea82 100644
--- a/drivers/hid/hid-roccat-kone.h
+++ b/drivers/hid/hid-roccat-kone.h
@@ -14,8 +14,6 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17#define ROCCAT_KONE_DRIVER_VERSION "v0.3.1"
18
19#pragma pack(push) 17#pragma pack(push)
20#pragma pack(1) 18#pragma pack(1)
21 19
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index e05d48edb66f..f6e80c7ca61e 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -168,7 +168,7 @@ static int roccat_open(struct inode *inode, struct file *file)
168 printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", 168 printk(KERN_EMERG "roccat device with minor %d doesn't exist\n",
169 minor); 169 minor);
170 error = -ENODEV; 170 error = -ENODEV;
171 goto exit_unlock; 171 goto exit_err;
172 } 172 }
173 173
174 if (!device->open++) { 174 if (!device->open++) {
@@ -178,7 +178,7 @@ static int roccat_open(struct inode *inode, struct file *file)
178 PM_HINT_FULLON); 178 PM_HINT_FULLON);
179 if (error < 0) { 179 if (error < 0) {
180 --device->open; 180 --device->open;
181 goto exit_unlock; 181 goto exit_err;
182 } 182 }
183 } 183 }
184 error = device->hid->ll_driver->open(device->hid); 184 error = device->hid->ll_driver->open(device->hid);
@@ -187,7 +187,7 @@ static int roccat_open(struct inode *inode, struct file *file)
187 device->hid->ll_driver->power(device->hid, 187 device->hid->ll_driver->power(device->hid,
188 PM_HINT_NORMAL); 188 PM_HINT_NORMAL);
189 --device->open; 189 --device->open;
190 goto exit_unlock; 190 goto exit_err;
191 } 191 }
192 } 192 }
193 193
@@ -202,6 +202,9 @@ exit_unlock:
202 mutex_unlock(&device->readers_lock); 202 mutex_unlock(&device->readers_lock);
203 mutex_unlock(&devices_lock); 203 mutex_unlock(&devices_lock);
204 return error; 204 return error;
205exit_err:
206 kfree(reader);
207 goto exit_unlock;
205} 208}
206 209
207static int roccat_release(struct inode *inode, struct file *file) 210static int roccat_release(struct inode *inode, struct file *file)
diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h
index d8aae0c1fa7e..09e864e9f79d 100644
--- a/drivers/hid/hid-roccat.h
+++ b/drivers/hid/hid-roccat.h
@@ -15,7 +15,7 @@
15#include <linux/hid.h> 15#include <linux/hid.h>
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18#if defined(CONFIG_HID_ROCCAT) || defined (CONFIG_HID_ROCCAT_MODULE) 18#if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE)
19int roccat_connect(struct hid_device *hid); 19int roccat_connect(struct hid_device *hid);
20void roccat_disconnect(int minor); 20void roccat_disconnect(int minor);
21int roccat_report_event(int minor, u8 const *data, int len); 21int roccat_report_event(int minor, u8 const *data, int len);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 2eebdcc57bcf..5771f851f856 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -6,6 +6,9 @@
6 * 6 *
7 * Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by 7 * Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by
8 * Wayne Thomas 2010. 8 * Wayne Thomas 2010.
9 *
10 * Modified to support Conceptronic CLLRCMCE by
11 * Kees Bakker 2010.
9 */ 12 */
10 13
11/* 14/*
@@ -34,6 +37,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
34 case 0x00d: ts_map_key_clear(KEY_MEDIA); break; 37 case 0x00d: ts_map_key_clear(KEY_MEDIA); break;
35 case 0x024: ts_map_key_clear(KEY_MENU); break; 38 case 0x024: ts_map_key_clear(KEY_MENU); break;
36 case 0x025: ts_map_key_clear(KEY_TV); break; 39 case 0x025: ts_map_key_clear(KEY_TV); break;
40 case 0x027: ts_map_key_clear(KEY_MODE); break;
37 case 0x031: ts_map_key_clear(KEY_AUDIO); break; 41 case 0x031: ts_map_key_clear(KEY_AUDIO); break;
38 case 0x032: ts_map_key_clear(KEY_TEXT); break; 42 case 0x032: ts_map_key_clear(KEY_TEXT); break;
39 case 0x033: ts_map_key_clear(KEY_CHANNEL); break; 43 case 0x033: ts_map_key_clear(KEY_CHANNEL); break;
@@ -60,6 +64,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
60static const struct hid_device_id ts_devices[] = { 64static const struct hid_device_id ts_devices[] = {
61 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 65 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
62 { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, 66 { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
67 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
63 { } 68 { }
64}; 69};
65MODULE_DEVICE_TABLE(hid, ts_devices); 70MODULE_DEVICE_TABLE(hid, ts_devices);
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 1e051f1171e4..807dcd1555a6 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -436,7 +436,7 @@ static void wacom_remove(struct hid_device *hdev)
436 436
437static const struct hid_device_id wacom_devices[] = { 437static const struct hid_device_id wacom_devices[] = {
438 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 438 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
439 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, 439
440 { } 440 { }
441}; 441};
442MODULE_DEVICE_TABLE(hid, wacom_devices); 442MODULE_DEVICE_TABLE(hid, wacom_devices);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 3ccd47850677..47d70c523d93 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -46,7 +46,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
46{ 46{
47 struct hidraw_list *list = file->private_data; 47 struct hidraw_list *list = file->private_data;
48 int ret = 0, len; 48 int ret = 0, len;
49 char *report;
50 DECLARE_WAITQUEUE(wait, current); 49 DECLARE_WAITQUEUE(wait, current);
51 50
52 mutex_lock(&list->read_mutex); 51 mutex_lock(&list->read_mutex);
@@ -84,7 +83,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
84 if (ret) 83 if (ret)
85 goto out; 84 goto out;
86 85
87 report = list->buffer[list->tail].value;
88 len = list->buffer[list->tail].len > count ? 86 len = list->buffer[list->tail].len > count ?
89 count : list->buffer[list->tail].len; 87 count : list->buffer[list->tail].len;
90 88
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 5f5aa39b3988..2643d3147621 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -75,6 +75,8 @@ static const struct hid_blacklist {
75 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 75 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
76 { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 76 { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
77 77
78 { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
79
78 { 0, 0 } 80 { 0, 0 }
79}; 81};
80 82
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index c24d2fa3e3b6..254a003af048 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -67,7 +67,7 @@ struct hiddev_list {
67 struct mutex thread_lock; 67 struct mutex thread_lock;
68}; 68};
69 69
70static struct hiddev *hiddev_table[HIDDEV_MINORS]; 70static struct usb_driver hiddev_driver;
71 71
72/* 72/*
73 * Find a report, given the report's type and ID. The ID can be specified 73 * Find a report, given the report's type and ID. The ID can be specified
@@ -265,22 +265,19 @@ static int hiddev_release(struct inode * inode, struct file * file)
265static int hiddev_open(struct inode *inode, struct file *file) 265static int hiddev_open(struct inode *inode, struct file *file)
266{ 266{
267 struct hiddev_list *list; 267 struct hiddev_list *list;
268 int res, i; 268 struct usb_interface *intf;
269 269 struct hiddev *hiddev;
270 /* See comment in hiddev_connect() for BKL explanation */ 270 int res;
271 lock_kernel();
272 i = iminor(inode) - HIDDEV_MINOR_BASE;
273 271
274 if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i]) 272 intf = usb_find_interface(&hiddev_driver, iminor(inode));
273 if (!intf)
275 return -ENODEV; 274 return -ENODEV;
275 hiddev = usb_get_intfdata(intf);
276 276
277 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) 277 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
278 return -ENOMEM; 278 return -ENOMEM;
279 mutex_init(&list->thread_lock); 279 mutex_init(&list->thread_lock);
280 280 list->hiddev = hiddev;
281 list->hiddev = hiddev_table[i];
282
283
284 file->private_data = list; 281 file->private_data = list;
285 282
286 /* 283 /*
@@ -289,7 +286,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
289 */ 286 */
290 if (list->hiddev->exist) { 287 if (list->hiddev->exist) {
291 if (!list->hiddev->open++) { 288 if (!list->hiddev->open++) {
292 res = usbhid_open(hiddev_table[i]->hid); 289 res = usbhid_open(hiddev->hid);
293 if (res < 0) { 290 if (res < 0) {
294 res = -EIO; 291 res = -EIO;
295 goto bail; 292 goto bail;
@@ -301,12 +298,12 @@ static int hiddev_open(struct inode *inode, struct file *file)
301 } 298 }
302 299
303 spin_lock_irq(&list->hiddev->list_lock); 300 spin_lock_irq(&list->hiddev->list_lock);
304 list_add_tail(&list->node, &hiddev_table[i]->list); 301 list_add_tail(&list->node, &hiddev->list);
305 spin_unlock_irq(&list->hiddev->list_lock); 302 spin_unlock_irq(&list->hiddev->list_lock);
306 303
307 if (!list->hiddev->open++) 304 if (!list->hiddev->open++)
308 if (list->hiddev->exist) { 305 if (list->hiddev->exist) {
309 struct hid_device *hid = hiddev_table[i]->hid; 306 struct hid_device *hid = hiddev->hid;
310 res = usbhid_get_power(hid); 307 res = usbhid_get_power(hid);
311 if (res < 0) { 308 if (res < 0) {
312 res = -EIO; 309 res = -EIO;
@@ -314,13 +311,10 @@ static int hiddev_open(struct inode *inode, struct file *file)
314 } 311 }
315 usbhid_open(hid); 312 usbhid_open(hid);
316 } 313 }
317
318 unlock_kernel();
319 return 0; 314 return 0;
320bail: 315bail:
321 file->private_data = NULL; 316 file->private_data = NULL;
322 kfree(list); 317 kfree(list);
323 unlock_kernel();
324 return res; 318 return res;
325} 319}
326 320
@@ -894,37 +888,14 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
894 hid->hiddev = hiddev; 888 hid->hiddev = hiddev;
895 hiddev->hid = hid; 889 hiddev->hid = hid;
896 hiddev->exist = 1; 890 hiddev->exist = 1;
897 891 usb_set_intfdata(usbhid->intf, usbhid);
898 /*
899 * BKL here is used to avoid race after usb_register_dev().
900 * Once the device node has been created, open() could happen on it.
901 * The code below will then fail, as hiddev_table hasn't been
902 * updated.
903 *
904 * The obvious fix -- introducing mutex to guard hiddev_table[]
905 * doesn't work, as usb_open() and usb_register_dev() both take
906 * minor_rwsem, thus we'll have ABBA deadlock.
907 *
908 * Before BKL pushdown, usb_open() had been acquiring it in right
909 * order, so _open() was safe to use it to protect from this race.
910 * Now the order is different, but AB-BA deadlock still doesn't occur
911 * as BKL is dropped on schedule() (i.e. while sleeping on
912 * minor_rwsem). Fugly.
913 */
914 lock_kernel();
915 retval = usb_register_dev(usbhid->intf, &hiddev_class); 892 retval = usb_register_dev(usbhid->intf, &hiddev_class);
916 if (retval) { 893 if (retval) {
917 err_hid("Not able to get a minor for this device."); 894 err_hid("Not able to get a minor for this device.");
918 hid->hiddev = NULL; 895 hid->hiddev = NULL;
919 unlock_kernel();
920 kfree(hiddev); 896 kfree(hiddev);
921 return -1; 897 return -1;
922 } else {
923 hid->minor = usbhid->intf->minor;
924 hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
925 } 898 }
926 unlock_kernel();
927
928 return 0; 899 return 0;
929} 900}
930 901
@@ -942,7 +913,6 @@ void hiddev_disconnect(struct hid_device *hid)
942 hiddev->exist = 0; 913 hiddev->exist = 0;
943 mutex_unlock(&hiddev->existancelock); 914 mutex_unlock(&hiddev->existancelock);
944 915
945 hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
946 usb_deregister_dev(usbhid->intf, &hiddev_class); 916 usb_deregister_dev(usbhid->intf, &hiddev_class);
947 917
948 if (hiddev->open) { 918 if (hiddev->open) {