]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.20-iForce2.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / linux-2.4.20-iForce2.patch
CommitLineData
6c693fec 1diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/Documentation/input/ff.txt linux-modified/Documentation/input/ff.txt
2--- linux-vanilla/Documentation/input/ff.txt Thu Sep 13 00:34:06 2001
3+++ linux-modified/Documentation/input/ff.txt Mon Jan 6 16:48:20 2003
4@@ -1,6 +1,7 @@
5 Force feedback for Linux.
6 By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
7-
8+You may redistribute this file. Please remember to include shape.fig and
9+interactive.fig as well.
10 ----------------------------------------------------------------------------
11
12 0. Introduction
13@@ -38,13 +39,10 @@
14
15 You then need to insert the modules into the following order:
16 % modprobe joydev
17-% modprobe serport
18+% modprobe serport # Only for serial
19 % modprobe iforce
20 % modprobe evdev
21 % ./inputattach -ifor $2 & # Only for serial
22-For convenience, you may use the shell script named "ff" available from
23-the cvs tree of the Linux Console Project at sourceforge. You can also
24-retrieve it from http://www.esil.univ-mrs.fr/~jdeneux/projects/ff/.
25 If you are using USB, you don't need the inputattach step.
26
27 Please check that you have all the /dev/input entries needed:
28@@ -68,7 +66,7 @@
29 2.1 Does it work ?
30 ~~~~~~~~~~~~~~~~~~
31 There is an utility called fftest that will allow you to test the driver.
32-% fftest /dev/eventXX
33+% fftest /dev/input/eventXX
34
35 3. Instructions to the developper
36 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37@@ -81,22 +79,30 @@
38 #include <linux/input.h>
39 #include <sys/ioctl.h>
40
41+unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
42 int ioctl(int file_descriptor, int request, unsigned long *features);
43
44-"request" must be EVIOCGBIT(EV_FF, sizeof(unsigned long))
45+"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
46
47 Returns the features supported by the device. features is a bitfield with the
48 following bits:
49-- FF_X has an X axis (should allways be the case)
50-- FF_Y has an Y axis (usually not the case for wheels)
51+- FF_X has an X axis (usually joysticks)
52+- FF_Y has an Y axis (usually joysticks)
53+- FF_WHEEL has a wheel (usually sterring wheels)
54 - FF_CONSTANT can render constant force effects
55-- FF_PERIODIC can render periodic effects (sine, ramp, square...)
56+- FF_PERIODIC can render periodic effects (sine, triangle, square...)
57+- FF_RAMP can render ramp effects
58 - FF_SPRING can simulate the presence of a spring
59-- FF_FRICTION can simulate friction (aka drag, damper effect...)
60+- FF_FRICTION can simulate friction
61+- FF_DAMPER can simulate damper effects
62 - FF_RUMBLE rumble effects (normally the only effect supported by rumble
63 pads)
64-- 8 bits from FF_N_EFFECTS_0 containing the number of effects that can be
65- simultaneously played.
66+- FF_INERTIA can simulate inertia
67+
68+
69+int ioctl(int fd, EVIOCGEFFECTS, int *n);
70+
71+Returns the number of effects the device can keep in its memory.
72
73 3.2 Uploading effects to the device
74 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
75@@ -112,7 +118,11 @@
76 The content of effect may be modified. In particular, its field "id" is set
77 to the unique id assigned by the driver. This data is required for performing
78 some operations (removing an effect, controlling the playback).
79-See <linux/input.h> for a description of the ff_effect stuct.
80+This if field must be set to -1 by the user in order to tell the driver to
81+allocate a new effect.
82+See <linux/input.h> for a description of the ff_effect stuct. You should also
83+find help in a few sketches, contained in files shape.fig and interactive.fig.
84+You need xfig to visualize these files.
85
86 3.3 Removing an effect from the device
87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88@@ -187,8 +197,31 @@
89
90 3.7 Dynamic update of an effect
91 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92-This consists in changing some parameters of an effect while it's playing. The
93-driver currently does not support that. You still have the brute-force method,
94-which consists in erasing the effect and uploading the updated version. It
95-actually works pretty well. You don't need to stop-and-start the effect.
96+Proceed as if you wanted to upload a new effect, except that instead of
97+setting the id field to -1, you set it to the wanted effect id.
98+Normally, the effect is not stopped and restarted. However, depending on the
99+type of device, not all paramaters can be dynamically updated. For example,
100+the direction of an effect cannot be updated with iforce devices. In this
101+case, the driver stops the effect, up-load it, and restart it.
102+
103+
104+3.8 Information about the status of effects
105+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106+Every time the status of an effect is changed, an event is sent. The values
107+and meanings of the fields of the event are as follows:
108+struct input_event {
109+/* When the status of the effect changed */
110+ struct timeval time;
111+
112+/* Set to EV_FF_STATUS */
113+ unsigned short type;
114+
115+/* Contains the id of the effect */
116+ unsigned short code;
117+
118+/* Indicates the status */
119+ unsigned int value;
120+};
121
122+FF_STATUS_STOPPED The effect stopped playing
123+FF_STATUS_PLAYING The effect started to play
124diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/Documentation/input/interactive.fig linux-modified/Documentation/input/interactive.fig
125--- linux-vanilla/Documentation/input/interactive.fig Thu Jan 1 02:00:00 1970
126+++ linux-modified/Documentation/input/interactive.fig Mon Jan 6 16:48:20 2003
127@@ -0,0 +1,42 @@
128+#FIG 3.2
129+Landscape
130+Center
131+Inches
132+Letter
133+100.00
134+Single
135+-2
136+1200 2
137+2 1 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 6
138+ 1200 3600 1800 3600 2400 4800 3000 4800 4200 5700 4800 5700
139+2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5
140+ 1200 3150 4800 3150 4800 6300 1200 6300 1200 3150
141+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
142+ 1200 4800 4800 4800
143+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
144+ 2400 4800 2400 6525 1950 7125 1950 7800
145+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
146+ 3000 4800 3000 6525 3600 7125 3600 7800
147+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 1 3
148+ 0 0 1.00 60.00 120.00
149+ 3825 5400 4125 5100 5400 5100
150+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 1 3
151+ 0 0 1.00 60.00 120.00
152+ 2100 4200 2400 3900 5400 3900
153+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
154+ 4800 5700 5400 5700
155+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
156+ 1800 3600 5400 3600
157+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 1 3
158+ 0 0 1.00 60.00 120.00
159+ 2700 4800 2700 4425 5400 4425
160+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
161+ 0 0 1.00 60.00 120.00
162+ 0 0 1.00 60.00 120.00
163+ 1950 7800 3600 7800
164+4 1 0 50 0 0 12 0.0000 4 135 810 2775 7725 Dead band\001
165+4 0 0 50 0 0 12 0.0000 4 180 1155 5400 5700 right saturation\001
166+4 0 0 50 0 0 12 0.0000 4 135 1065 5400 3600 left saturation\001
167+4 0 0 50 0 0 12 0.0000 4 180 2505 5400 3900 left coeff ( positive in that case )\001
168+4 0 0 50 0 0 12 0.0000 4 180 2640 5475 5100 right coeff ( negative in that case )\001
169+4 0 0 50 0 0 12 0.0000 4 105 480 5400 4425 center\001
170diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/Documentation/input/joystick.txt linux-modified/Documentation/input/joystick.txt
171--- linux-vanilla/Documentation/input/joystick.txt Thu Sep 13 00:34:06 2001
172+++ linux-modified/Documentation/input/joystick.txt Mon Jan 6 16:48:20 2003
173@@ -1,7 +1,7 @@
174 Linux Joystick driver v2.0.0
175- (c) 1996-2000 Vojtech Pavlik <vojtech@suse.cz>
176+ (c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
177 Sponsored by SuSE
178- $Id$
179+ $Id$
180 ----------------------------------------------------------------------------
181
182 0. Disclaimer
183@@ -21,8 +21,8 @@
184 Temple Place, Suite 330, Boston, MA 02111-1307 USA
185
186 Should you need to contact me, the author, you can do so either by e-mail
187-- mail your message to <vojtech@suse.cz>, or by paper mail: Vojtech Pavlik,
188-Ucitelska 1576, Prague 8, 182 00 Czech Republic
189+- mail your message to <vojtech@ucw.cz>, or by paper mail: Vojtech Pavlik,
190+Simunkova 1594, Prague 8, 182 00 Czech Republic
191
192 For your convenience, the GNU General Public License version 2 is included
193 in the package: See the file COPYING.
194@@ -111,7 +111,7 @@
195 alias tty-ldisc-2 serport
196 alias char-major-13 input
197 above input joydev ns558 analog
198- options analog js=gameport
199+ options analog js=gamepad
200
201 2.5 Verifying that it works
202 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
203@@ -503,15 +503,16 @@
204
205 3.21 I-Force devices
206 ~~~~~~~~~~~~~~~~~~~~
207- All I-Force devices are supported by the iforce.c module. This includes:
208+ All I-Force devices are supported by the iforce.o module. This includes:
209
210 * AVB Mag Turbo Force
211 * AVB Top Shot Pegasus
212+* AVB Top Shot Force Feedback Racing Wheel
213 * Logitech WingMan Force
214-* Logitech WingMan Force 3D
215 * Logitech WingMan Force Wheel
216-* Logitech WingMan Strike Force 3D
217 * Guillemot Race Leader Force Feedback
218+* Guillemot Force Feedback Racing Wheel
219+* Thrustmaster Motor Sport GT
220
221 To use it, you need to attach the serial port to the driver using the
222
223@@ -524,6 +525,10 @@
224 isn't needed.
225
226 The I-Force driver now supports force feedback via the event interface.
227+
228+ Please note that Logitech WingMan *3D devices are _not_ supported by this
229+module, rather by hid. Force feedback is not supported for those devices.
230+Logitech gamepads are also hid devices.
231
232 3.22 Gravis Stinger gamepad
233 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
234diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/Documentation/input/shape.fig linux-modified/Documentation/input/shape.fig
235--- linux-vanilla/Documentation/input/shape.fig Thu Jan 1 02:00:00 1970
236+++ linux-modified/Documentation/input/shape.fig Mon Jan 6 16:48:20 2003
237@@ -0,0 +1,65 @@
238+#FIG 3.2
239+Landscape
240+Center
241+Inches
242+Letter
243+100.00
244+Single
245+-2
246+1200 2
247+2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 6
248+ 4200 3600 4200 3075 4950 2325 7425 2325 8250 3150 8250 3600
249+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
250+ 4200 3675 4200 5400
251+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
252+ 8250 3675 8250 5400
253+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
254+ 3675 3600 8700 3600
255+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
256+ 8775 3600 10200 3600
257+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
258+ 8325 3150 9075 3150
259+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
260+ 7500 2325 10200 2325
261+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
262+ 3600 3600 3000 3600
263+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
264+ 4125 3075 3000 3075
265+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
266+ 0 0 1.00 60.00 120.00
267+ 0 0 1.00 60.00 120.00
268+ 4200 5400 8175 5400
269+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
270+ 0 0 1.00 60.00 120.00
271+ 0 0 1.00 60.00 120.00
272+ 10125 2325 10125 3600
273+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
274+ 0 0 1.00 60.00 120.00
275+ 0 0 1.00 60.00 120.00
276+ 3000 3150 3000 3600
277+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
278+ 0 0 1.00 60.00 120.00
279+ 0 0 1.00 60.00 120.00
280+ 9075 3150 9075 3600
281+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
282+ 4950 2325 4950 1200
283+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
284+ 7425 2325 7425 1200
285+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
286+ 4200 3075 4200 2400 3600 1800 3600 1200
287+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
288+ 8250 3150 8250 2475 8775 1950 8775 1200
289+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
290+ 0 0 1.00 60.00 120.00
291+ 0 0 1.00 60.00 120.00
292+ 3600 1275 4950 1275
293+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
294+ 0 0 1.00 60.00 120.00
295+ 0 0 1.00 60.00 120.00
296+ 7425 1275 8700 1275
297+4 1 0 50 0 0 12 0.0000 4 135 1140 6075 5325 Effect duration\001
298+4 0 0 50 0 0 12 0.0000 4 180 1305 10200 3000 Effect magnitude\001
299+4 0 0 50 0 0 12 0.0000 4 135 780 9150 3450 Fade level\001
300+4 1 0 50 0 0 12 0.0000 4 180 1035 4275 1200 Attack length\001
301+4 1 0 50 0 0 12 0.0000 4 180 885 8175 1200 Fade length\001
302+4 2 0 50 0 0 12 0.0000 4 135 930 2925 3375 Attack level\001
303diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/Config.in linux-modified/drivers/char/joystick/Config.in
304--- linux-vanilla/drivers/char/joystick/Config.in Fri Nov 29 01:53:12 2002
305+++ linux-modified/drivers/char/joystick/Config.in Mon Jan 6 16:48:20 2003
306@@ -32,8 +32,7 @@
307 dep_tristate ' InterAct digital joysticks and gamepads' CONFIG_INPUT_INTERACT $CONFIG_INPUT $CONFIG_INPUT_GAMEPORT
308 dep_tristate ' ThrustMaster DirectConnect joysticks and gamepads' CONFIG_INPUT_TMDC $CONFIG_INPUT $CONFIG_INPUT_GAMEPORT
309 dep_tristate ' Microsoft SideWinder digital joysticks and gamepads' CONFIG_INPUT_SIDEWINDER $CONFIG_INPUT $CONFIG_INPUT_GAMEPORT
310- dep_tristate ' I-Force USB joysticks and wheels' CONFIG_INPUT_IFORCE_USB $CONFIG_INPUT $CONFIG_USB
311- dep_tristate ' I-Force Serial joysticks and wheels' CONFIG_INPUT_IFORCE_232 $CONFIG_INPUT $CONFIG_INPUT_SERIO
312+ source drivers/char/joystick/iforce/Config.in
313 dep_tristate ' Logitech WingMan Warrior joystick' CONFIG_INPUT_WARRIOR $CONFIG_INPUT $CONFIG_INPUT_SERIO
314 dep_tristate ' LogiCad3d Magellan/SpaceMouse 6dof controller' CONFIG_INPUT_MAGELLAN $CONFIG_INPUT $CONFIG_INPUT_SERIO
315 dep_tristate ' SpaceTec SpaceOrb/Avenger 6dof controller' CONFIG_INPUT_SPACEORB $CONFIG_INPUT $CONFIG_INPUT_SERIO
316diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/Makefile linux-modified/drivers/char/joystick/Makefile
317--- linux-vanilla/drivers/char/joystick/Makefile Fri Nov 29 01:53:12 2002
318+++ linux-modified/drivers/char/joystick/Makefile Mon Jan 6 16:54:09 2003
319@@ -8,19 +8,6 @@
320
321 export-objs := serio.o gameport.o pcigame.o
322
323-# I-Force may need both USB and RS-232
324-
325-ifeq ($(CONFIG_INPUT_IFORCE_232),m)
326- ifeq ($(CONFIG_INPUT_IFORCE_USB),y)
327- CONFIG_INPUT_IFORCE_USB := m
328- endif
329-endif
330-ifeq ($(CONFIG_INPUT_IFORCE_USB),m)
331- ifeq ($(CONFIG_INPUT_IFORCE_232),y)
332- CONFIG_INPUT_IFORCE_232 := m
333- endif
334-endif
335-
336 # Object file lists.
337
338 obj-y :=
339@@ -46,8 +33,6 @@
340 obj-$(CONFIG_INPUT_SPACEORB) += spaceorb.o
341 obj-$(CONFIG_INPUT_SPACEBALL) += spaceball.o
342 obj-$(CONFIG_INPUT_STINGER) += stinger.o
343-obj-$(CONFIG_INPUT_IFORCE_232) += iforce.o
344-obj-$(CONFIG_INPUT_IFORCE_USB) += iforce.o
345
346 obj-$(CONFIG_INPUT_ANALOG) += analog.o
347 obj-$(CONFIG_INPUT_A3D) += a3d.o
348@@ -64,6 +49,8 @@
349 obj-$(CONFIG_INPUT_TURBOGRAFX) += turbografx.o
350
351 obj-$(CONFIG_INPUT_AMIJOY) += amijoy.o
352+
353+subdir-$(CONFIG_JOYSTICK_IFORCE) += iforce
354
355 # The global Rules.make.
356
357diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/a3d.c linux-modified/drivers/char/joystick/a3d.c
358--- linux-vanilla/drivers/char/joystick/a3d.c Sat Aug 3 02:39:43 2002
359+++ linux-modified/drivers/char/joystick/a3d.c Mon Jan 6 16:48:20 2003
360@@ -347,8 +347,8 @@
361 a3d->dev.idversion = 0x0100;
362
363 input_register_device(&a3d->dev);
364- printk(KERN_INFO "input%d: %s on gameport%d.0\n",
365- a3d->dev.number, a3d_names[a3d->mode], gameport->number);
366+ printk(KERN_INFO "input: %s on gameport%d.0\n",
367+ a3d_names[a3d->mode], gameport->number);
368
369 return;
370 fail2: gameport_close(gameport);
371diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/adi.c linux-modified/drivers/char/joystick/adi.c
372--- linux-vanilla/drivers/char/joystick/adi.c Thu Sep 13 00:34:06 2001
373+++ linux-modified/drivers/char/joystick/adi.c Mon Jan 6 16:48:20 2003
374@@ -514,8 +514,8 @@
375 if (port->adi[i].length > 0) {
376 adi_init_center(port->adi + i);
377 input_register_device(&port->adi[i].dev);
378- printk(KERN_INFO "input%d: %s [%s] on gameport%d.%d\n",
379- port->adi[i].dev.number, port->adi[i].name, port->adi[i].cname, gameport->number, i);
380+ printk(KERN_INFO "input: %s [%s] on gameport%d.%d\n",
381+ port->adi[i].name, port->adi[i].cname, gameport->number, i);
382 }
383 }
384
385diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/analog.c linux-modified/drivers/char/joystick/analog.c
386--- linux-vanilla/drivers/char/joystick/analog.c Fri Nov 29 01:53:12 2002
387+++ linux-modified/drivers/char/joystick/analog.c Mon Jan 6 16:48:20 2003
388@@ -490,8 +490,8 @@
389
390 input_register_device(&analog->dev);
391
392- printk(KERN_INFO "input%d: %s at gameport%d.%d",
393- analog->dev.number, analog->name, port->gameport->number, index);
394+ printk(KERN_INFO "input: %s at gameport%d.%d",
395+ analog->name, port->gameport->number, index);
396
397 if (port->cooked)
398 printk(" [ADC port]\n");
399diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/cobra.c linux-modified/drivers/char/joystick/cobra.c
400--- linux-vanilla/drivers/char/joystick/cobra.c Thu Sep 13 00:34:06 2001
401+++ linux-modified/drivers/char/joystick/cobra.c Mon Jan 6 16:48:20 2003
402@@ -208,8 +208,8 @@
403 cobra->dev[i].absmin[ABS_Y] = -1; cobra->dev[i].absmax[ABS_Y] = 1;
404
405 input_register_device(cobra->dev + i);
406- printk(KERN_INFO "input%d: %s on gameport%d.%d\n",
407- cobra->dev[i].number, cobra_name, gameport->number, i);
408+ printk(KERN_INFO "input: %s on gameport%d.%d\n",
409+ cobra_name, gameport->number, i);
410 }
411
412
413diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/db9.c linux-modified/drivers/char/joystick/db9.c
414--- linux-vanilla/drivers/char/joystick/db9.c Thu Sep 13 00:34:06 2001
415+++ linux-modified/drivers/char/joystick/db9.c Mon Jan 6 16:48:20 2003
416@@ -362,8 +362,8 @@
417 db9->dev[i].absmin[ABS_Y] = -1; db9->dev[i].absmax[ABS_Y] = 1;
418
419 input_register_device(db9->dev + i);
420- printk(KERN_INFO "input%d: %s on %s\n",
421- db9->dev[i].number, db9_name[db9->mode], db9->pd->port->name);
422+ printk(KERN_INFO "input: %s on %s\n",
423+ db9_name[db9->mode], db9->pd->port->name);
424 }
425
426 return db9;
427diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/gamecon.c linux-modified/drivers/char/joystick/gamecon.c
428--- linux-vanilla/drivers/char/joystick/gamecon.c Thu Sep 13 00:34:06 2001
429+++ linux-modified/drivers/char/joystick/gamecon.c Mon Jan 6 16:48:20 2003
430@@ -608,7 +608,7 @@
431 for (i = 0; i < 5; i++)
432 if (gc->pads[0] & gc_status_bit[i]) {
433 input_register_device(gc->dev + i);
434- printk(KERN_INFO "input%d: %s on %s\n", gc->dev[i].number, gc->dev[i].name, gc->pd->port->name);
435+ printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
436 }
437
438 return gc;
439diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/gf2k.c linux-modified/drivers/char/joystick/gf2k.c
440--- linux-vanilla/drivers/char/joystick/gf2k.c Thu Sep 13 00:34:06 2001
441+++ linux-modified/drivers/char/joystick/gf2k.c Mon Jan 6 16:48:20 2003
442@@ -323,8 +323,8 @@
443 }
444
445 input_register_device(&gf2k->dev);
446- printk(KERN_INFO "input%d: %s on gameport%d.0\n",
447- gf2k->dev.number, gf2k_names[gf2k->id], gameport->number);
448+ printk(KERN_INFO "input: %s on gameport%d.0\n",
449+ gf2k_names[gf2k->id], gameport->number);
450
451 return;
452 fail2: gameport_close(gameport);
453diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/grip.c linux-modified/drivers/char/joystick/grip.c
454--- linux-vanilla/drivers/char/joystick/grip.c Thu Sep 13 00:34:06 2001
455+++ linux-modified/drivers/char/joystick/grip.c Mon Jan 6 16:48:20 2003
456@@ -382,8 +382,8 @@
457
458 input_register_device(grip->dev + i);
459
460- printk(KERN_INFO "input%d: %s on gameport%d.%d\n",
461- grip->dev[i].number, grip_name[grip->mode[i]], gameport->number, i);
462+ printk(KERN_INFO "input: %s on gameport%d.%d\n",
463+ grip_name[grip->mode[i]], gameport->number, i);
464 }
465
466 return;
467diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/Config.help linux-modified/drivers/char/joystick/iforce/Config.help
468--- linux-vanilla/drivers/char/joystick/iforce/Config.help Thu Jan 1 02:00:00 1970
469+++ linux-modified/drivers/char/joystick/iforce/Config.help Mon Jan 6 16:48:20 2003
470@@ -0,0 +1,21 @@
471+CONFIG_JOYSTICK_IFORCE
472+ Say Y here if you have an I-Force joystick or steering wheel
473+
474+ You also must choose at least one of the two options below.
475+
476+ This driver is also available as a module ( = code which can be
477+ inserted in and removed from the running kernel whenever you want).
478+ The module will be called iforce.o. If you want to compile it as a
479+ module, say M here and read <file:Documentation/modules.txt>.
480+
481+CONFIG_JOYSTICK_IFORCE_USB
482+ Say Y here if you have an I-Force joystick or steering wheel
483+ connected to your USB port.
484+
485+CONFIG_JOYSTICK_IFORCE_232
486+ Say Y here if you have an I-Force joystick or steering wheel
487+ connected to your serial (COM) port.
488+
489+ You will need an additional utility called inputattach, see
490+ Documentation/input/joystick.txt and ff.txt.
491+
492diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/Config.in linux-modified/drivers/char/joystick/iforce/Config.in
493--- linux-vanilla/drivers/char/joystick/iforce/Config.in Thu Jan 1 02:00:00 1970
494+++ linux-modified/drivers/char/joystick/iforce/Config.in Mon Jan 6 16:48:20 2003
495@@ -0,0 +1,14 @@
496+#
497+# I-Force driver configuration
498+#
499+
500+dep_tristate 'I-Force devices' CONFIG_JOYSTICK_IFORCE $CONFIG_INPUT $CONFIG_INPUT_JOYSTICK
501+
502+if [ "$CONFIG_JOYSTICK_IFORCE" = "m" -o "$CONFIG_JOYSTICK_IFORCE" = "y" ]; then
503+ if [ "$CONFIG_JOYSTICK_IFORCE" = "m" -o "$CONFIG_USB" = "y" ]; then
504+ dep_mbool ' I-Force USB joysticks and wheels' CONFIG_JOYSTICK_IFORCE_USB $CONFIG_USB
505+ fi
506+ if [ "$CONFIG_JOYSTICK_IFORCE" = "m" -o "$CONFIG_INPUT_SERIO" = "y" ]; then
507+ dep_mbool ' I-Force Serial joysticks and wheels' CONFIG_JOYSTICK_IFORCE_232 $CONFIG_INPUT_SERIO
508+ fi
509+fi
510diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/Makefile linux-modified/drivers/char/joystick/iforce/Makefile
511--- linux-vanilla/drivers/char/joystick/iforce/Makefile Thu Jan 1 02:00:00 1970
512+++ linux-modified/drivers/char/joystick/iforce/Makefile Mon Jan 6 16:48:20 2003
513@@ -0,0 +1,30 @@
514+#
515+# Makefile for the I-Force driver
516+#
517+# By Johann Deneux <deneux@ifrance.com>
518+#
519+
520+# Goal definition
521+list-multi := iforce.o
522+iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o
523+
524+obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
525+
526+ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y)
527+ iforce-objs += iforce-serio.o
528+endif
529+
530+ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y)
531+ iforce-objs += iforce-usb.o
532+endif
533+
534+EXTRA_CFLAGS = -Werror-implicit-function-declaration
535+
536+# The global Rules.make.
537+
538+include $(TOPDIR)/Rules.make
539+
540+# Additional rules
541+iforce.o: $(iforce-objs)
542+ $(LD) -r -o $@ $(iforce-objs)
543+
544diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/iforce-ff.c linux-modified/drivers/char/joystick/iforce/iforce-ff.c
545--- linux-vanilla/drivers/char/joystick/iforce/iforce-ff.c Thu Jan 1 02:00:00 1970
546+++ linux-modified/drivers/char/joystick/iforce/iforce-ff.c Mon Jan 6 16:48:20 2003
547@@ -0,0 +1,544 @@
548+/*
549+ * $Id$
550+ *
551+ * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
552+ * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
553+ *
554+ * USB/RS232 I-Force joysticks and wheels.
555+ */
556+
557+/*
558+ * This program is free software; you can redistribute it and/or modify
559+ * it under the terms of the GNU General Public License as published by
560+ * the Free Software Foundation; either version 2 of the License, or
561+ * (at your option) any later version.
562+ *
563+ * This program is distributed in the hope that it will be useful,
564+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
565+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
566+ * GNU General Public License for more details.
567+ *
568+ * You should have received a copy of the GNU General Public License
569+ * along with this program; if not, write to the Free Software
570+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
571+ *
572+ * Should you need to contact me, the author, you can do so either by
573+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
574+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
575+ */
576+
577+#include "iforce.h"
578+
579+/*
580+ * Set the magnitude of a constant force effect
581+ * Return error code
582+ *
583+ * Note: caller must ensure exclusive access to device
584+ */
585+
586+static int make_magnitude_modifier(struct iforce* iforce,
587+ struct resource* mod_chunk, int no_alloc, __s16 level)
588+{
589+ unsigned char data[3];
590+
591+ if (!no_alloc) {
592+ down(&iforce->mem_mutex);
593+ if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
594+ iforce->device_memory.start, iforce->device_memory.end, 2L,
595+ NULL, NULL)) {
596+ up(&iforce->mem_mutex);
597+ return -ENOMEM;
598+ }
599+ up(&iforce->mem_mutex);
600+ }
601+
602+ data[0] = LO(mod_chunk->start);
603+ data[1] = HI(mod_chunk->start);
604+ data[2] = HIFIX80(level);
605+
606+ iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data);
607+
608+// iforce_dump_packet("magnitude: ", FF_CMD_MAGNITUDE, data);
609+ return 0;
610+}
611+
612+/*
613+ * Upload the component of an effect dealing with the period, phase and magnitude
614+ */
615+
616+static int make_period_modifier(struct iforce* iforce,
617+ struct resource* mod_chunk, int no_alloc,
618+ __s16 magnitude, __s16 offset, u16 period, u16 phase)
619+{
620+ unsigned char data[7];
621+
622+ period = TIME_SCALE(period);
623+
624+ if (!no_alloc) {
625+ down(&iforce->mem_mutex);
626+ if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
627+ iforce->device_memory.start, iforce->device_memory.end, 2L,
628+ NULL, NULL)) {
629+ up(&iforce->mem_mutex);
630+ return -ENOMEM;
631+ }
632+ up(&iforce->mem_mutex);
633+ }
634+
635+ data[0] = LO(mod_chunk->start);
636+ data[1] = HI(mod_chunk->start);
637+
638+ data[2] = HIFIX80(magnitude);
639+ data[3] = HIFIX80(offset);
640+ data[4] = HI(phase);
641+
642+ data[5] = LO(period);
643+ data[6] = HI(period);
644+
645+ iforce_send_packet(iforce, FF_CMD_PERIOD, data);
646+
647+ return 0;
648+}
649+
650+/*
651+ * Uploads the part of an effect setting the envelope of the force
652+ */
653+
654+static int make_envelope_modifier(struct iforce* iforce,
655+ struct resource* mod_chunk, int no_alloc,
656+ u16 attack_duration, __s16 initial_level,
657+ u16 fade_duration, __s16 final_level)
658+{
659+ unsigned char data[8];
660+
661+ attack_duration = TIME_SCALE(attack_duration);
662+ fade_duration = TIME_SCALE(fade_duration);
663+
664+ if (!no_alloc) {
665+ down(&iforce->mem_mutex);
666+ if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
667+ iforce->device_memory.start, iforce->device_memory.end, 2L,
668+ NULL, NULL)) {
669+ up(&iforce->mem_mutex);
670+ return -ENOMEM;
671+ }
672+ up(&iforce->mem_mutex);
673+ }
674+
675+ data[0] = LO(mod_chunk->start);
676+ data[1] = HI(mod_chunk->start);
677+
678+ data[2] = LO(attack_duration);
679+ data[3] = HI(attack_duration);
680+ data[4] = HI(initial_level);
681+
682+ data[5] = LO(fade_duration);
683+ data[6] = HI(fade_duration);
684+ data[7] = HI(final_level);
685+
686+ iforce_send_packet(iforce, FF_CMD_ENVELOPE, data);
687+
688+ return 0;
689+}
690+
691+/*
692+ * Component of spring, friction, inertia... effects
693+ */
694+
695+static int make_condition_modifier(struct iforce* iforce,
696+ struct resource* mod_chunk, int no_alloc,
697+ __u16 rsat, __u16 lsat, __s16 rk, __s16 lk, u16 db, __s16 center)
698+{
699+ unsigned char data[10];
700+
701+ if (!no_alloc) {
702+ down(&iforce->mem_mutex);
703+ if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
704+ iforce->device_memory.start, iforce->device_memory.end, 2L,
705+ NULL, NULL)) {
706+ up(&iforce->mem_mutex);
707+ return -ENOMEM;
708+ }
709+ up(&iforce->mem_mutex);
710+ }
711+
712+ data[0] = LO(mod_chunk->start);
713+ data[1] = HI(mod_chunk->start);
714+
715+ data[2] = (100*rk)>>15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
716+ data[3] = (100*lk)>>15; /* This code is incorrect on cpus lacking arith shift */
717+
718+ center = (500*center)>>15;
719+ data[4] = LO(center);
720+ data[5] = HI(center);
721+
722+ db = (1000*db)>>16;
723+ data[6] = LO(db);
724+ data[7] = HI(db);
725+
726+ data[8] = (100*rsat)>>16;
727+ data[9] = (100*lsat)>>16;
728+
729+ iforce_send_packet(iforce, FF_CMD_CONDITION, data);
730+// iforce_dump_packet("condition", FF_CMD_CONDITION, data);
731+
732+ return 0;
733+}
734+
735+static unsigned char find_button(struct iforce *iforce, signed short button)
736+{
737+ int i;
738+ for (i = 1; iforce->type->btn[i] >= 0; i++)
739+ if (iforce->type->btn[i] == button)
740+ return i + 1;
741+ return 0;
742+}
743+
744+/*
745+ * Analyse the changes in an effect, and tell if we need to send an condition
746+ * parameter packet
747+ */
748+static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
749+{
750+ int id = new->id;
751+ struct ff_effect* old = &iforce->core_effects[id].effect;
752+ int ret=0;
753+ int i;
754+
755+ if (new->type != FF_SPRING && new->type != FF_FRICTION) {
756+ printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
757+ return FALSE;
758+ }
759+
760+ for(i=0; i<2; i++) {
761+ ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation
762+ || old->u.condition[i].left_saturation != new->u.condition[i].left_saturation
763+ || old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
764+ || old->u.condition[i].left_coeff != new->u.condition[i].left_coeff
765+ || old->u.condition[i].deadband != new->u.condition[i].deadband
766+ || old->u.condition[i].center != new->u.condition[i].center;
767+ }
768+ return ret;
769+}
770+
771+/*
772+ * Analyse the changes in an effect, and tell if we need to send a magnitude
773+ * parameter packet
774+ */
775+static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect)
776+{
777+ int id = effect->id;
778+ struct ff_effect* old = &iforce->core_effects[id].effect;
779+
780+ if (effect->type != FF_CONSTANT) {
781+ printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
782+ return FALSE;
783+ }
784+
785+ return (old->u.constant.level != effect->u.constant.level);
786+}
787+
788+/*
789+ * Analyse the changes in an effect, and tell if we need to send an envelope
790+ * parameter packet
791+ */
792+static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect)
793+{
794+ int id = effect->id;
795+ struct ff_effect* old = &iforce->core_effects[id].effect;
796+
797+ switch (effect->type) {
798+ case FF_CONSTANT:
799+ if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length
800+ || old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level
801+ || old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length
802+ || old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
803+ return TRUE;
804+ break;
805+
806+ case FF_PERIODIC:
807+ if (old->u.periodic.envelope.attack_length != effect->u.periodic.envelope.attack_length
808+ || old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level
809+ || old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length
810+ || old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
811+ return TRUE;
812+ break;
813+
814+ default:
815+ printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
816+ }
817+
818+ return FALSE;
819+}
820+
821+/*
822+ * Analyse the changes in an effect, and tell if we need to send a periodic
823+ * parameter effect
824+ */
825+static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
826+{
827+ int id = new->id;
828+ struct ff_effect* old = &iforce->core_effects[id].effect;
829+
830+ if (new->type != FF_PERIODIC) {
831+ printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");
832+ return FALSE;
833+ }
834+
835+ return (old->u.periodic.period != new->u.periodic.period
836+ || old->u.periodic.magnitude != new->u.periodic.magnitude
837+ || old->u.periodic.offset != new->u.periodic.offset
838+ || old->u.periodic.phase != new->u.periodic.phase);
839+}
840+
841+/*
842+ * Analyse the changes in an effect, and tell if we need to send an effect
843+ * packet
844+ */
845+static int need_core(struct iforce* iforce, struct ff_effect* new)
846+{
847+ int id = new->id;
848+ struct ff_effect* old = &iforce->core_effects[id].effect;
849+
850+ if (old->direction != new->direction
851+ || old->trigger.button != new->trigger.button
852+ || old->trigger.interval != new->trigger.interval
853+ || old->replay.length != new->replay.length
854+ || old->replay.delay != new->replay.delay)
855+ return TRUE;
856+
857+ return FALSE;
858+}
859+/*
860+ * Send the part common to all effects to the device
861+ */
862+static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
863+ u8 effect_type, u8 axes, u16 duration, u16 delay, u16 button,
864+ u16 interval, u16 direction)
865+{
866+ unsigned char data[14];
867+
868+ duration = TIME_SCALE(duration);
869+ delay = TIME_SCALE(delay);
870+ interval = TIME_SCALE(interval);
871+
872+ data[0] = LO(id);
873+ data[1] = effect_type;
874+ data[2] = LO(axes) | find_button(iforce, button);
875+
876+ if (!duration) duration = 0xFFFF;
877+ data[3] = LO(duration);
878+ data[4] = HI(duration);
879+
880+ data[5] = HI(direction);
881+
882+ data[6] = LO(interval);
883+ data[7] = HI(interval);
884+
885+ data[8] = LO(mod_id1);
886+ data[9] = HI(mod_id1);
887+ data[10] = LO(mod_id2);
888+ data[11] = HI(mod_id2);
889+
890+ data[12] = LO(delay);
891+ data[13] = HI(delay);
892+
893+ /* Stop effect */
894+/* iforce_control_playback(iforce, id, 0);*/
895+
896+ iforce_send_packet(iforce, FF_CMD_EFFECT, data);
897+
898+ /* If needed, restart effect */
899+ if (test_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[id].flags)) {
900+ /* BUG: perhaps we should replay n times, instead of 1. But we do not know n */
901+ iforce_control_playback(iforce, id, 1);
902+ }
903+
904+ return 0;
905+}
906+
907+/*
908+ * Upload a periodic effect to the device
909+ * See also iforce_upload_constant.
910+ */
911+int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update)
912+{
913+ u8 wave_code;
914+ int core_id = effect->id;
915+ struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
916+ struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
917+ struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
918+ int param1_err = 1;
919+ int param2_err = 1;
920+ int core_err = 0;
921+
922+ if (!is_update || need_period_modifier(iforce, effect)) {
923+ param1_err = make_period_modifier(iforce, mod1_chunk,
924+ is_update,
925+ effect->u.periodic.magnitude, effect->u.periodic.offset,
926+ effect->u.periodic.period, effect->u.periodic.phase);
927+ if (param1_err) return param1_err;
928+ set_bit(FF_MOD1_IS_USED, core_effect->flags);
929+ }
930+
931+ if (!is_update || need_envelope_modifier(iforce, effect)) {
932+ param2_err = make_envelope_modifier(iforce, mod2_chunk,
933+ is_update,
934+ effect->u.periodic.envelope.attack_length,
935+ effect->u.periodic.envelope.attack_level,
936+ effect->u.periodic.envelope.fade_length,
937+ effect->u.periodic.envelope.fade_level);
938+ if (param2_err) return param2_err;
939+ set_bit(FF_MOD2_IS_USED, core_effect->flags);
940+ }
941+
942+ switch (effect->u.periodic.waveform) {
943+ case FF_SQUARE: wave_code = 0x20; break;
944+ case FF_TRIANGLE: wave_code = 0x21; break;
945+ case FF_SINE: wave_code = 0x22; break;
946+ case FF_SAW_UP: wave_code = 0x23; break;
947+ case FF_SAW_DOWN: wave_code = 0x24; break;
948+ default: wave_code = 0x20; break;
949+ }
950+
951+ if (!is_update || need_core(iforce, effect)) {
952+ core_err = make_core(iforce, effect->id,
953+ mod1_chunk->start,
954+ mod2_chunk->start,
955+ wave_code,
956+ 0x20,
957+ effect->replay.length,
958+ effect->replay.delay,
959+ effect->trigger.button,
960+ effect->trigger.interval,
961+ effect->direction);
962+ }
963+
964+ /* If one of the parameter creation failed, we already returned an
965+ * error code.
966+ * If the core creation failed, we return its error code.
967+ * Else: if one parameter at least was created, we return 0
968+ * else we return 1;
969+ */
970+ return core_err < 0 ? core_err : (param1_err && param2_err);
971+}
972+
973+/*
974+ * Upload a constant force effect
975+ * Return value:
976+ * <0 Error code
977+ * 0 Ok, effect created or updated
978+ * 1 effect did not change since last upload, and no packet was therefore sent
979+ */
980+int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update)
981+{
982+ int core_id = effect->id;
983+ struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
984+ struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
985+ struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
986+ int param1_err = 1;
987+ int param2_err = 1;
988+ int core_err = 0;
989+
990+ if (!is_update || need_magnitude_modifier(iforce, effect)) {
991+ param1_err = make_magnitude_modifier(iforce, mod1_chunk,
992+ is_update,
993+ effect->u.constant.level);
994+ if (param1_err) return param1_err;
995+ set_bit(FF_MOD1_IS_USED, core_effect->flags);
996+ }
997+
998+ if (!is_update || need_envelope_modifier(iforce, effect)) {
999+ param2_err = make_envelope_modifier(iforce, mod2_chunk,
1000+ is_update,
1001+ effect->u.constant.envelope.attack_length,
1002+ effect->u.constant.envelope.attack_level,
1003+ effect->u.constant.envelope.fade_length,
1004+ effect->u.constant.envelope.fade_level);
1005+ if (param2_err) return param2_err;
1006+ set_bit(FF_MOD2_IS_USED, core_effect->flags);
1007+ }
1008+
1009+ if (!is_update || need_core(iforce, effect)) {
1010+ core_err = make_core(iforce, effect->id,
1011+ mod1_chunk->start,
1012+ mod2_chunk->start,
1013+ 0x00,
1014+ 0x20,
1015+ effect->replay.length,
1016+ effect->replay.delay,
1017+ effect->trigger.button,
1018+ effect->trigger.interval,
1019+ effect->direction);
1020+ }
1021+
1022+ /* If one of the parameter creation failed, we already returned an
1023+ * error code.
1024+ * If the core creation failed, we return its error code.
1025+ * Else: if one parameter at least was created, we return 0
1026+ * else we return 1;
1027+ */
1028+ return core_err < 0 ? core_err : (param1_err && param2_err);
1029+}
1030+
1031+/*
1032+ * Upload an condition effect. Those are for example friction, inertia, springs...
1033+ */
1034+int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update)
1035+{
1036+ int core_id = effect->id;
1037+ struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
1038+ struct resource* mod1_chunk = &(core_effect->mod1_chunk);
1039+ struct resource* mod2_chunk = &(core_effect->mod2_chunk);
1040+ u8 type;
1041+ int param_err = 1;
1042+ int core_err = 0;
1043+
1044+ switch (effect->type) {
1045+ case FF_SPRING: type = 0x40; break;
1046+ case FF_DAMPER: type = 0x41; break;
1047+ default: return -1;
1048+ }
1049+
1050+ if (!is_update || need_condition_modifier(iforce, effect)) {
1051+ param_err = make_condition_modifier(iforce, mod1_chunk,
1052+ is_update,
1053+ effect->u.condition[0].right_saturation,
1054+ effect->u.condition[0].left_saturation,
1055+ effect->u.condition[0].right_coeff,
1056+ effect->u.condition[0].left_coeff,
1057+ effect->u.condition[0].deadband,
1058+ effect->u.condition[0].center);
1059+ if (param_err) return param_err;
1060+ set_bit(FF_MOD1_IS_USED, core_effect->flags);
1061+
1062+ param_err = make_condition_modifier(iforce, mod2_chunk,
1063+ is_update,
1064+ effect->u.condition[1].right_saturation,
1065+ effect->u.condition[1].left_saturation,
1066+ effect->u.condition[1].right_coeff,
1067+ effect->u.condition[1].left_coeff,
1068+ effect->u.condition[1].deadband,
1069+ effect->u.condition[1].center);
1070+ if (param_err) return param_err;
1071+ set_bit(FF_MOD2_IS_USED, core_effect->flags);
1072+
1073+ }
1074+
1075+ if (!is_update || need_core(iforce, effect)) {
1076+ core_err = make_core(iforce, effect->id,
1077+ mod1_chunk->start, mod2_chunk->start,
1078+ type, 0xc0,
1079+ effect->replay.length, effect->replay.delay,
1080+ effect->trigger.button, effect->trigger.interval,
1081+ effect->direction);
1082+ }
1083+
1084+ /* If the parameter creation failed, we already returned an
1085+ * error code.
1086+ * If the core creation failed, we return its error code.
1087+ * Else: if a parameter was created, we return 0
1088+ * else we return 1;
1089+ */
1090+ return core_err < 0 ? core_err : param_err;
1091+}
1092diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/iforce-main.c linux-modified/drivers/char/joystick/iforce/iforce-main.c
1093--- linux-vanilla/drivers/char/joystick/iforce/iforce-main.c Thu Jan 1 02:00:00 1970
1094+++ linux-modified/drivers/char/joystick/iforce/iforce-main.c Wed Feb 26 20:36:04 2003
1095@@ -0,0 +1,562 @@
1096+/*
1097+ * $Id$
1098+ *
1099+ * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
1100+ * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
1101+ *
1102+ * USB/RS232 I-Force joysticks and wheels.
1103+ */
1104+
1105+/*
1106+ * This program is free software; you can redistribute it and/or modify
1107+ * it under the terms of the GNU General Public License as published by
1108+ * the Free Software Foundation; either version 2 of the License, or
1109+ * (at your option) any later version.
1110+ *
1111+ * This program is distributed in the hope that it will be useful,
1112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1114+ * GNU General Public License for more details.
1115+ *
1116+ * You should have received a copy of the GNU General Public License
1117+ * along with this program; if not, write to the Free Software
1118+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1119+ *
1120+ * Should you need to contact me, the author, you can do so either by
1121+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
1122+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
1123+ */
1124+
1125+#include "iforce.h"
1126+
1127+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <deneux@ifrance.com>");
1128+MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
1129+MODULE_LICENSE("GPL");
1130+
1131+#define USB_VENDOR_ID_SAITEK 0x06a3
1132+#define USB_PRODUCT_ID_CYBORGFORCE 0xff12
1133+
1134+
1135+static signed short btn_joystick[] =
1136+{ BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
1137+ BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
1138+
1139+static signed short btn_avb_pegasus[] =
1140+{ BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
1141+ BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
1142+
1143+static signed short btn_wheel[] =
1144+{ BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
1145+ BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
1146+
1147+static signed short btn_avb_tw[] =
1148+{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE,
1149+ BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
1150+
1151+static signed short btn_avb_wheel[] =
1152+{ BTN_GEAR_DOWN, BTN_GEAR_UP, BTN_BASE, BTN_BASE2, BTN_BASE3,
1153+ BTN_BASE4, BTN_BASE5, BTN_BASE6, -1 };
1154+
1155+static signed short abs_joystick[] =
1156+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
1157+
1158+static signed short abs_avb_pegasus[] =
1159+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
1160+ ABS_HAT1X, ABS_HAT1Y, -1 };
1161+
1162+static signed short abs_wheel[] =
1163+{ ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, -1 };
1164+
1165+static signed short btn_saitek_joystick[] =
1166+{ BTN_TRIGGER, BTN_TOP2, BTN_THUMB,BTN_THUMB2, BTN_TOP,
1167+ BTN_BASE, BTN_BASE2, BTN_BASE4, BTN_BASE3, -1 };
1168+
1169+static signed short abs_saitek_joystick[] =
1170+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER,ABS_HAT0X, ABS_HAT0Y, -1 };
1171+
1172+
1173+
1174+static signed short ff_iforce[] =
1175+{ FF_PERIODIC, FF_CONSTANT, FF_SPRING, FF_DAMPER,
1176+ FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP, FF_SAW_DOWN, FF_GAIN,
1177+ FF_AUTOCENTER, -1 };
1178+
1179+static struct iforce_device iforce_device[] = {
1180+ { 0x044f, 0xa01c, "Thrustmaster Motor Sport GT", btn_wheel, abs_wheel, ff_iforce },
1181+ { 0x046d, 0xc281, "Logitech WingMan Force", btn_joystick, abs_joystick, ff_iforce },
1182+ { 0x046d, 0xc291, "Logitech WingMan Formula Force", btn_wheel, abs_wheel, ff_iforce },
1183+ { 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_avb_pegasus, abs_avb_pegasus, ff_iforce },
1184+ { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce },
1185+ { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //?
1186+ { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //?
1187+ { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //?
1188+ { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //?
1189+ { 0x06a3, 0xff12, "Saitek Cyborgforce", btn_saitek_joystick, abs_saitek_joystick, ff_iforce },
1190+ { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce }
1191+};
1192+
1193+
1194+
1195+static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
1196+{
1197+ struct iforce* iforce = (struct iforce*)(dev->private);
1198+ unsigned char data[3];
1199+
1200+ if (type != EV_FF)
1201+ return -1;
1202+
1203+ switch (code) {
1204+
1205+ case FF_GAIN:
1206+
1207+ data[0] = value >> 9;
1208+ iforce_send_packet(iforce, FF_CMD_GAIN, data);
1209+
1210+ return 0;
1211+
1212+ case FF_AUTOCENTER:
1213+
1214+ data[0] = 0x03;
1215+ data[1] = value >> 9;
1216+ iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
1217+
1218+ data[0] = 0x04;
1219+ data[1] = 0x01;
1220+ iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
1221+
1222+ return 0;
1223+
1224+ default: /* Play or stop an effect */
1225+
1226+ if (value > 0) {
1227+ set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
1228+ }
1229+ else {
1230+ clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
1231+ }
1232+
1233+ iforce_control_playback(iforce, code, value);
1234+ return 0;
1235+ }
1236+
1237+ return -1;
1238+}
1239+
1240+/*
1241+ * Function called when an ioctl is performed on the event dev entry.
1242+ * It uploads an effect to the device
1243+ */
1244+static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
1245+{
1246+ struct iforce* iforce = (struct iforce*)(dev->private);
1247+ int id;
1248+ int ret;
1249+ int is_update;
1250+
1251+/* Check this effect type is supported by this device */
1252+ if (!test_bit(effect->type, iforce->dev.ffbit))
1253+ return -EINVAL;
1254+
1255+/*
1256+ * If we want to create a new effect, get a free id
1257+ */
1258+ if (effect->id == -1) {
1259+
1260+ for (id=0; id < FF_EFFECTS_MAX; ++id)
1261+ if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
1262+
1263+ if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
1264+ return -ENOMEM;
1265+
1266+ effect->id = id;
1267+ iforce->core_effects[id].owner = current->pid;
1268+ iforce->core_effects[id].flags[0] = (1<<FF_CORE_IS_USED); /* Only IS_USED bit must be set */
1269+
1270+ is_update = FALSE;
1271+ }
1272+ else {
1273+ /* We want to update an effect */
1274+ /* Parameter type cannot be updated */
1275+ if (effect->type != iforce->core_effects[effect->id].effect.type)
1276+ return -EINVAL;
1277+
1278+ /* Check the effect is not already being updated */
1279+ if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) {
1280+ return -EAGAIN;
1281+ }
1282+
1283+ is_update = TRUE;
1284+ }
1285+
1286+/*
1287+ * Upload the effect
1288+ */
1289+ switch (effect->type) {
1290+
1291+ case FF_PERIODIC:
1292+ ret = iforce_upload_periodic(iforce, effect, is_update);
1293+ break;
1294+
1295+ case FF_CONSTANT:
1296+ ret = iforce_upload_constant(iforce, effect, is_update);
1297+ break;
1298+
1299+ case FF_SPRING:
1300+ case FF_DAMPER:
1301+ ret = iforce_upload_condition(iforce, effect, is_update);
1302+ break;
1303+
1304+ default:
1305+ return -EINVAL;
1306+ }
1307+ if (ret == 0) {
1308+ /* A packet was sent, forbid new updates until we are notified
1309+ * that the packet was updated
1310+ */
1311+ set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags);
1312+ }
1313+ iforce->core_effects[effect->id].effect = *effect;
1314+ return ret;
1315+}
1316+
1317+/*
1318+ * Erases an effect: it frees the effect id and mark as unused the memory
1319+ * allocated for the parameters
1320+ */
1321+static int iforce_erase_effect(struct input_dev *dev, int effect_id)
1322+{
1323+ struct iforce* iforce = (struct iforce*)(dev->private);
1324+ int err = 0;
1325+ struct iforce_core_effect* core_effect;
1326+
1327+ if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
1328+ return -EINVAL;
1329+
1330+ core_effect = iforce->core_effects + effect_id;
1331+
1332+ if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
1333+ err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk));
1334+
1335+ if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
1336+ err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk));
1337+
1338+ /*TODO: remember to change that if more FF_MOD* bits are added */
1339+ core_effect->flags[0] = 0;
1340+
1341+ return err;
1342+}
1343+
1344+static int iforce_open(struct input_dev *dev)
1345+{
1346+ struct iforce *iforce = dev->private;
1347+
1348+ switch (iforce->bus) {
1349+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1350+ case IFORCE_USB:
1351+ iforce->irq->dev = iforce->usbdev;
1352+ if (usb_submit_urb(iforce->irq))
1353+ return -EIO;
1354+ break;
1355+#endif
1356+ }
1357+
1358+ /* Enable force feedback */
1359+ iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
1360+
1361+ return 0;
1362+}
1363+
1364+static int iforce_flush(struct input_dev *dev, struct file *file)
1365+{
1366+ struct iforce *iforce = dev->private;
1367+ int i;
1368+
1369+ /* Erase all effects this process owns */
1370+ for (i=0; i<dev->ff_effects_max; ++i) {
1371+
1372+ if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
1373+ current->pid == iforce->core_effects[i].owner) {
1374+
1375+ /* Stop effect */
1376+ input_report_ff(dev, i, 0);
1377+
1378+ /* Free ressources assigned to effect */
1379+ if (iforce_erase_effect(dev, i)) {
1380+ printk(KERN_WARNING "iforce_flush: erase effect %d failed\n", i);
1381+ }
1382+ }
1383+
1384+ }
1385+ return 0;
1386+}
1387+
1388+static void iforce_release(struct input_dev *dev)
1389+{
1390+ struct iforce *iforce = dev->private;
1391+ int i;
1392+
1393+ /* Check: no effect should be present in memory */
1394+ for (i=0; i<dev->ff_effects_max; ++i) {
1395+ if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags))
1396+ break;
1397+ }
1398+ if (i<dev->ff_effects_max) {
1399+ printk(KERN_WARNING "iforce_release: Device still owns effects\n");
1400+ }
1401+
1402+ /* Disable force feedback playback */
1403+ iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
1404+
1405+ switch (iforce->bus) {
1406+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1407+ case IFORCE_USB:
1408+ usb_unlink_urb(iforce->irq);
1409+
1410+ /* The device was unplugged before the file
1411+ * was released */
1412+ if (iforce->usbdev == NULL) {
1413+ iforce_delete_device(iforce);
1414+ kfree(iforce);
1415+ }
1416+ break;
1417+#endif
1418+ }
1419+}
1420+
1421+void iforce_delete_device(struct iforce *iforce)
1422+{
1423+ switch (iforce->bus) {
1424+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1425+ case IFORCE_USB:
1426+ iforce_usb_delete(iforce);
1427+ break;
1428+#endif
1429+#ifdef CONFIG_JOYSTICK_IFORCE_232
1430+ case IFORCE_232:
1431+ //TODO: Wait for the last packets to be sent
1432+ break;
1433+#endif
1434+ }
1435+}
1436+
1437+int iforce_init_device(struct iforce *iforce)
1438+{
1439+ unsigned char c[] = "CEOV";
1440+ int i;
1441+
1442+ init_waitqueue_head(&iforce->wait);
1443+ spin_lock_init(&iforce->xmit_lock);
1444+ init_MUTEX(&iforce->mem_mutex);
1445+ iforce->xmit.buf = iforce->xmit_data;
1446+
1447+ iforce->dev.ff_effects_max = 10;
1448+
1449+/*
1450+ * Input device fields.
1451+ */
1452+
1453+ iforce->dev.idbus = BUS_USB;
1454+ iforce->dev.private = iforce;
1455+ iforce->dev.name = "Unknown I-Force device";
1456+ iforce->dev.open = iforce_open;
1457+ iforce->dev.close = iforce_release;
1458+ iforce->dev.flush = iforce_flush;
1459+ iforce->dev.event = iforce_input_event;
1460+ iforce->dev.upload_effect = iforce_upload_effect;
1461+ iforce->dev.erase_effect = iforce_erase_effect;
1462+
1463+/*
1464+ * On-device memory allocation.
1465+ */
1466+
1467+ iforce->device_memory.name = "I-Force device effect memory";
1468+ iforce->device_memory.start = 0;
1469+ iforce->device_memory.end = 200;
1470+ iforce->device_memory.flags = IORESOURCE_MEM;
1471+ iforce->device_memory.parent = NULL;
1472+ iforce->device_memory.child = NULL;
1473+ iforce->device_memory.sibling = NULL;
1474+
1475+/*
1476+ * Wait until device ready - until it sends its first response.
1477+ */
1478+
1479+ for (i = 0; i < 20; i++)
1480+ if (!iforce_get_id_packet(iforce, "O"))
1481+ break;
1482+
1483+ if (i == 20) { /* 5 seconds */
1484+ printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n");
1485+ return -1;
1486+ }
1487+
1488+/*
1489+ * Get device info.
1490+ */
1491+
1492+ if (!iforce_get_id_packet(iforce, "M"))
1493+ iforce->dev.idvendor = (iforce->edata[2] << 8) | iforce->edata[1];
1494+ else
1495+ printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n");
1496+
1497+ if (!iforce_get_id_packet(iforce, "P"))
1498+ iforce->dev.idproduct = (iforce->edata[2] << 8) | iforce->edata[1];
1499+ else
1500+ printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n");
1501+
1502+ if (!iforce_get_id_packet(iforce, "B"))
1503+ iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
1504+ else
1505+ printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
1506+
1507+ if (!iforce_get_id_packet(iforce, "N"))
1508+ iforce->dev.ff_effects_max = iforce->edata[1];
1509+ else
1510+ printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
1511+
1512+ /* Check if the device can store more effects than the driver can really handle */
1513+ if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) {
1514+ printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
1515+ iforce->dev.ff_effects_max, FF_EFFECTS_MAX);
1516+ iforce->dev.ff_effects_max = FF_EFFECTS_MAX;
1517+ }
1518+
1519+/*
1520+ * Display additional info.
1521+ */
1522+
1523+ for (i = 0; c[i]; i++)
1524+ if (!iforce_get_id_packet(iforce, c + i))
1525+ iforce_dump_packet("info", iforce->ecmd, iforce->edata);
1526+
1527+/*
1528+ * Disable spring, enable force feedback.
1529+ * FIXME: We should use iforce_set_autocenter() et al here.
1530+ */
1531+
1532+ iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
1533+
1534+/*
1535+ * Find appropriate device entry
1536+ */
1537+
1538+ for (i = 0; iforce_device[i].idvendor; i++)
1539+ if (iforce_device[i].idvendor == iforce->dev.idvendor &&
1540+ iforce_device[i].idproduct == iforce->dev.idproduct)
1541+ break;
1542+
1543+ iforce->type = iforce_device + i;
1544+ iforce->dev.name = iforce->type->name;
1545+
1546+/*
1547+ * Set input device bitfields and ranges.
1548+ */
1549+
1550+ iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
1551+
1552+ for (i = 0; iforce->type->btn[i] >= 0; i++) {
1553+ signed short t = iforce->type->btn[i];
1554+ set_bit(t, iforce->dev.keybit);
1555+ }
1556+ set_bit(BTN_DEAD, iforce->dev.keybit);
1557+
1558+ for (i = 0; iforce->type->abs[i] >= 0; i++) {
1559+
1560+ signed short t = iforce->type->abs[i];
1561+ set_bit(t, iforce->dev.absbit);
1562+
1563+ switch (t) {
1564+
1565+ case ABS_X:
1566+ case ABS_Y:
1567+ case ABS_WHEEL:
1568+ if (iforce->dev.idvendor == USB_VENDOR_ID_SAITEK && iforce->dev.idproduct == USB_PRODUCT_ID_CYBORGFORCE)
1569+ {
1570+ iforce->dev.absmax[t] = 0x1000;
1571+ iforce->dev.absmin[t] = 0;
1572+ }
1573+ else {
1574+ iforce->dev.absmax[t] = 1920;
1575+ iforce->dev.absmin[t] = -1920;
1576+ }
1577+ iforce->dev.absflat[t] = 128;
1578+ iforce->dev.absfuzz[t] = 16;
1579+ set_bit(t, iforce->dev.ffbit);
1580+ break;
1581+
1582+ case ABS_THROTTLE:
1583+ case ABS_GAS:
1584+ case ABS_BRAKE:
1585+
1586+ iforce->dev.absmax[t] = 255;
1587+ iforce->dev.absmin[t] = 0;
1588+ break;
1589+
1590+ case ABS_RUDDER:
1591+ if (iforce->dev.idvendor == USB_VENDOR_ID_SAITEK && iforce->dev.idproduct == USB_PRODUCT_ID_CYBORGFORCE)
1592+ {
1593+ iforce->dev.absmax[t] = 255;
1594+ iforce->dev.absmin[t] = 0;
1595+ iforce->dev.absflat[t] = 10;
1596+ iforce->dev.absfuzz[t] = 4;
1597+
1598+ }
1599+ else
1600+ {
1601+ iforce->dev.absmax[t] = 127;
1602+ iforce->dev.absmin[t] = -128;
1603+
1604+ }
1605+ break;
1606+
1607+ case ABS_HAT0X:
1608+ case ABS_HAT0Y:
1609+ case ABS_HAT1X:
1610+ case ABS_HAT1Y:
1611+ iforce->dev.absmax[t] = 1;
1612+ iforce->dev.absmin[t] = -1;
1613+ break;
1614+ }
1615+ }
1616+
1617+ for (i = 0; iforce->type->ff[i] >= 0; i++)
1618+ set_bit(iforce->type->ff[i], iforce->dev.ffbit);
1619+
1620+/*
1621+ * Register input device.
1622+ */
1623+
1624+ input_register_device(&iforce->dev);
1625+
1626+ printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
1627+
1628+ printk(KERN_INFO "input: %s [%d effects, %ld bytes memory]\n",
1629+ iforce->dev.name, iforce->dev.ff_effects_max,
1630+ iforce->device_memory.end);
1631+
1632+ return 0;
1633+}
1634+
1635+static int __init iforce_init(void)
1636+{
1637+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1638+ usb_register(&iforce_usb_driver);
1639+#endif
1640+#ifdef CONFIG_JOYSTICK_IFORCE_232
1641+ serio_register_device(&iforce_serio_dev);
1642+#endif
1643+ return 0;
1644+}
1645+
1646+static void __exit iforce_exit(void)
1647+{
1648+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1649+ usb_deregister(&iforce_usb_driver);
1650+#endif
1651+#ifdef CONFIG_JOYSTICK_IFORCE_232
1652+ serio_unregister_device(&iforce_serio_dev);
1653+#endif
1654+}
1655+
1656+module_init(iforce_init);
1657+module_exit(iforce_exit);
1658diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/iforce-packets.c linux-modified/drivers/char/joystick/iforce/iforce-packets.c
1659--- linux-vanilla/drivers/char/joystick/iforce/iforce-packets.c Thu Jan 1 02:00:00 1970
1660+++ linux-modified/drivers/char/joystick/iforce/iforce-packets.c Mon Feb 17 21:28:41 2003
1661@@ -0,0 +1,320 @@
1662+/*
1663+ * $Id$
1664+ *
1665+ * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
1666+ * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
1667+ *
1668+ * USB/RS232 I-Force joysticks and wheels.
1669+ */
1670+
1671+/*
1672+ * This program is free software; you can redistribute it and/or modify
1673+ * it under the terms of the GNU General Public License as published by
1674+ * the Free Software Foundation; either version 2 of the License, or
1675+ * (at your option) any later version.
1676+ *
1677+ * This program is distributed in the hope that it will be useful,
1678+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1679+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1680+ * GNU General Public License for more details.
1681+ *
1682+ * You should have received a copy of the GNU General Public License
1683+ * along with this program; if not, write to the Free Software
1684+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1685+ *
1686+ * Should you need to contact me, the author, you can do so either by
1687+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
1688+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
1689+ */
1690+
1691+#include "iforce.h"
1692+
1693+static struct {
1694+ __s32 x;
1695+ __s32 y;
1696+} iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
1697+
1698+
1699+void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data)
1700+{
1701+ int i;
1702+
1703+ printk(KERN_DEBUG "iforce.c: %s ( cmd = %04x, data = ", msg, cmd);
1704+ for (i = 0; i < LO(cmd); i++)
1705+ printk("%02x ", data[i]);
1706+ printk(")\n");
1707+}
1708+
1709+/*
1710+ * Send a packet of bytes to the device
1711+ */
1712+int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
1713+{
1714+ /* Copy data to buffer */
1715+ int n = LO(cmd);
1716+ int c;
1717+ int empty;
1718+ int head, tail;
1719+ unsigned long flags;
1720+
1721+/*
1722+ * Update head and tail of xmit buffer
1723+ */
1724+ spin_lock_irqsave(&iforce->xmit_lock, flags);
1725+
1726+ head = iforce->xmit.head;
1727+ tail = iforce->xmit.tail;
1728+
1729+ if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) {
1730+ printk(KERN_WARNING "iforce.c: not enough space in xmit buffer to send new packet\n");
1731+ spin_unlock_irqrestore(&iforce->xmit_lock, flags);
1732+ return -1;
1733+ }
1734+
1735+ empty = head == tail;
1736+ XMIT_INC(iforce->xmit.head, n+2);
1737+
1738+/*
1739+ * Store packet in xmit buffer
1740+ */
1741+ iforce->xmit.buf[head] = HI(cmd);
1742+ XMIT_INC(head, 1);
1743+ iforce->xmit.buf[head] = LO(cmd);
1744+ XMIT_INC(head, 1);
1745+
1746+ c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE);
1747+ if (n < c) c=n;
1748+
1749+ memcpy(&iforce->xmit.buf[head],
1750+ data,
1751+ c);
1752+ if (n != c) {
1753+ memcpy(&iforce->xmit.buf[0],
1754+ data + c,
1755+ n - c);
1756+ }
1757+ XMIT_INC(head, n);
1758+
1759+ spin_unlock_irqrestore(&iforce->xmit_lock, flags);
1760+/*
1761+ * If necessary, start the transmission
1762+ */
1763+ switch (iforce->bus) {
1764+
1765+#ifdef CONFIG_JOYSTICK_IFORCE_232
1766+ case IFORCE_232:
1767+ if (empty)
1768+ iforce_serial_xmit(iforce);
1769+ break;
1770+#endif
1771+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1772+ case IFORCE_USB:
1773+
1774+ if (iforce->usbdev && empty &&
1775+ !test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
1776+
1777+ iforce_usb_xmit(iforce);
1778+ }
1779+ break;
1780+#endif
1781+ }
1782+ return 0;
1783+}
1784+
1785+/* Start or stop an effect */
1786+int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value)
1787+{
1788+ unsigned char data[3];
1789+
1790+//printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value);
1791+
1792+ data[0] = LO(id);
1793+ data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0;
1794+ data[2] = LO(value);
1795+ return iforce_send_packet(iforce, FF_CMD_PLAY, data);
1796+}
1797+
1798+/* Mark an effect that was being updated as ready. That means it can be updated
1799+ * again */
1800+static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
1801+{
1802+ int i;
1803+ for (i=0; i<iforce->dev.ff_effects_max; ++i) {
1804+ if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
1805+ (iforce->core_effects[i].mod1_chunk.start == addr ||
1806+ iforce->core_effects[i].mod2_chunk.start == addr)) {
1807+ clear_bit(FF_CORE_UPDATE, iforce->core_effects[i].flags);
1808+ return 0;
1809+ }
1810+ }
1811+ printk(KERN_WARNING "iforce-packets.c: unused effect %04x updated !!!\n", addr);
1812+ return -1;
1813+}
1814+
1815+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
1816+{
1817+ struct input_dev *dev = &iforce->dev;
1818+ int i;
1819+ static int being_used = 0;
1820+
1821+ if (being_used)
1822+ printk(KERN_WARNING "iforce-packets.c: re-entrant call to iforce_process %d\n", being_used);
1823+ being_used++;
1824+
1825+#ifdef CONFIG_JOYSTICK_IFORCE_232
1826+ if (HI(iforce->expect_packet) == HI(cmd)) {
1827+ iforce->expect_packet = 0;
1828+ iforce->ecmd = cmd;
1829+ memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
1830+ if (waitqueue_active(&iforce->wait))
1831+ wake_up(&iforce->wait);
1832+ }
1833+#endif
1834+
1835+ if (!iforce->type) {
1836+ being_used--;
1837+ return;
1838+ }
1839+
1840+ switch (HI(cmd)) {
1841+
1842+ case 0x01: /* joystick position data */
1843+ case 0x03: /* wheel position data */
1844+ case 0x06: /*saitek cyborgforve data */
1845+ if (HI(cmd) == 6) {
1846+ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
1847+ input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
1848+ input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
1849+ input_report_abs(dev, ABS_RUDDER, 255 - data[7]);
1850+ }
1851+ else if (HI(cmd) == 1) {
1852+ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
1853+ input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
1854+ input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
1855+ if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
1856+ input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
1857+ } else {
1858+ input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
1859+ input_report_abs(dev, ABS_GAS, 255 - data[2]);
1860+ input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
1861+ }
1862+
1863+ input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
1864+ input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
1865+
1866+ for (i = 0; iforce->type->btn[i] >= 0; i++)
1867+ input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7)));
1868+
1869+ /* If there are untouched bits left, interpret them as the second hat */
1870+ if (i <= 8) {
1871+ int btns = data[6];
1872+ if (test_bit(ABS_HAT1X, dev->absbit)) {
1873+ if (btns & 8) input_report_abs(dev, ABS_HAT1X, -1);
1874+ else if (btns & 2) input_report_abs(dev, ABS_HAT1X, 1);
1875+ else input_report_abs(dev, ABS_HAT1X, 0);
1876+ }
1877+ if (test_bit(ABS_HAT1Y, dev->absbit)) {
1878+ if (btns & 1) input_report_abs(dev, ABS_HAT1Y, -1);
1879+ else if (btns & 4) input_report_abs(dev, ABS_HAT1Y, 1);
1880+ else input_report_abs(dev, ABS_HAT1Y, 0);
1881+ }
1882+ }
1883+
1884+ break;
1885+
1886+ case 0x02: /* status report */
1887+ input_report_key(dev, BTN_DEAD, data[0] & 0x02);
1888+
1889+ /* Check if an effect was just started or stopped */
1890+ i = data[1] & 0x7f;
1891+ if (data[1] & 0x80) {
1892+ if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
1893+ /* Report play event */
1894+ input_report_ff_status(dev, i, FF_STATUS_PLAYING);
1895+ }
1896+ }
1897+ else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
1898+ /* Report stop event */
1899+ input_report_ff_status(dev, i, FF_STATUS_STOPPED);
1900+ }
1901+ if (LO(cmd) > 3) {
1902+ int j;
1903+ for (j=3; j<LO(cmd); j+=2) {
1904+ mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
1905+ }
1906+ }
1907+ break;
1908+ }
1909+ being_used--;
1910+}
1911+
1912+int iforce_get_id_packet(struct iforce *iforce, char *packet)
1913+{
1914+ DECLARE_WAITQUEUE(wait, current);
1915+ int timeout = HZ; /* 1 second */
1916+
1917+ switch (iforce->bus) {
1918+
1919+ case IFORCE_USB:
1920+
1921+#ifdef CONFIG_JOYSTICK_IFORCE_USB
1922+ iforce->dr.bRequest = packet[0];
1923+ iforce->ctrl->dev = iforce->usbdev;
1924+
1925+ set_current_state(TASK_INTERRUPTIBLE);
1926+ add_wait_queue(&iforce->wait, &wait);
1927+
1928+ if (usb_submit_urb(iforce->ctrl)) {
1929+ set_current_state(TASK_RUNNING);
1930+ remove_wait_queue(&iforce->wait, &wait);
1931+ return -1;
1932+ }
1933+
1934+ while (timeout && iforce->ctrl->status == -EINPROGRESS)
1935+ timeout = schedule_timeout(timeout);
1936+
1937+ set_current_state(TASK_RUNNING);
1938+ remove_wait_queue(&iforce->wait, &wait);
1939+
1940+ if (!timeout) {
1941+ usb_unlink_urb(iforce->ctrl);
1942+ return -1;
1943+ }
1944+#else
1945+ printk(KERN_ERR "iforce_get_id_packet: iforce->bus = USB!\n");
1946+#endif
1947+ break;
1948+
1949+ case IFORCE_232:
1950+
1951+#ifdef CONFIG_JOYSTICK_IFORCE_232
1952+ iforce->expect_packet = FF_CMD_QUERY;
1953+ iforce_send_packet(iforce, FF_CMD_QUERY, packet);
1954+
1955+ set_current_state(TASK_INTERRUPTIBLE);
1956+ add_wait_queue(&iforce->wait, &wait);
1957+
1958+ while (timeout && iforce->expect_packet)
1959+ timeout = schedule_timeout(timeout);
1960+
1961+ set_current_state(TASK_RUNNING);
1962+ remove_wait_queue(&iforce->wait, &wait);
1963+
1964+ if (!timeout) {
1965+ iforce->expect_packet = 0;
1966+ return -1;
1967+ }
1968+#else
1969+ printk(KERN_ERR "iforce_get_id_packet: iforce->bus = SERIO!\n");
1970+#endif
1971+ break;
1972+
1973+ default:
1974+ printk(KERN_ERR "iforce_get_id_packet: iforce->bus = %d\n",
1975+ iforce->bus);
1976+ break;
1977+ }
1978+
1979+ return -(iforce->edata[0] != packet[0]);
1980+}
1981+
1982diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/iforce-serio.c linux-modified/drivers/char/joystick/iforce/iforce-serio.c
1983--- linux-vanilla/drivers/char/joystick/iforce/iforce-serio.c Thu Jan 1 02:00:00 1970
1984+++ linux-modified/drivers/char/joystick/iforce/iforce-serio.c Mon Jan 6 16:48:20 2003
1985@@ -0,0 +1,166 @@
1986+/*
1987+ * $Id$
1988+ *
1989+ * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
1990+ * Copyright (c) 2001 Johann Deneux <deneux@ifrance.com>
1991+ *
1992+ * USB/RS232 I-Force joysticks and wheels.
1993+ */
1994+
1995+/*
1996+ * This program is free software; you can redistribute it and/or modify
1997+ * it under the terms of the GNU General Public License as published by
1998+ * the Free Software Foundation; either version 2 of the License, or
1999+ * (at your option) any later version.
2000+ *
2001+ * This program is distributed in the hope that it will be useful,
2002+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2003+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2004+ * GNU General Public License for more details.
2005+ *
2006+ * You should have received a copy of the GNU General Public License
2007+ * along with this program; if not, write to the Free Software
2008+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2009+ *
2010+ * Should you need to contact me, the author, you can do so either by
2011+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
2012+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
2013+ */
2014+
2015+#include "iforce.h"
2016+
2017+void iforce_serial_xmit(struct iforce *iforce)
2018+{
2019+ unsigned char cs;
2020+ int i;
2021+ unsigned long flags;
2022+
2023+ if (test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
2024+ set_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags);
2025+ return;
2026+ }
2027+
2028+ spin_lock_irqsave(&iforce->xmit_lock, flags);
2029+
2030+again:
2031+ if (iforce->xmit.head == iforce->xmit.tail) {
2032+ clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
2033+ spin_unlock_irqrestore(&iforce->xmit_lock, flags);
2034+ return;
2035+ }
2036+
2037+ cs = 0x2b;
2038+
2039+ serio_write(iforce->serio, 0x2b);
2040+
2041+ serio_write(iforce->serio, iforce->xmit.buf[iforce->xmit.tail]);
2042+ cs ^= iforce->xmit.buf[iforce->xmit.tail];
2043+ XMIT_INC(iforce->xmit.tail, 1);
2044+
2045+ for (i=iforce->xmit.buf[iforce->xmit.tail]; i >= 0; --i) {
2046+ serio_write(iforce->serio, iforce->xmit.buf[iforce->xmit.tail]);
2047+ cs ^= iforce->xmit.buf[iforce->xmit.tail];
2048+ XMIT_INC(iforce->xmit.tail, 1);
2049+ }
2050+
2051+ serio_write(iforce->serio, cs);
2052+
2053+ if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
2054+ goto again;
2055+
2056+ clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
2057+
2058+ spin_unlock_irqrestore(&iforce->xmit_lock, flags);
2059+}
2060+
2061+static void iforce_serio_write_wakeup(struct serio *serio)
2062+{
2063+ iforce_serial_xmit((struct iforce *)serio->private);
2064+}
2065+
2066+static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
2067+{
2068+ struct iforce* iforce = serio->private;
2069+
2070+ if (!iforce->pkt) {
2071+ if (data != 0x2b) {
2072+ return;
2073+ }
2074+ iforce->pkt = 1;
2075+ return;
2076+ }
2077+
2078+ if (!iforce->id) {
2079+ if (data > 3 && data != 0xff) {
2080+ iforce->pkt = 0;
2081+ return;
2082+ }
2083+ iforce->id = data;
2084+ return;
2085+ }
2086+
2087+ if (!iforce->len) {
2088+ if (data > IFORCE_MAX_LENGTH) {
2089+ iforce->pkt = 0;
2090+ iforce->id = 0;
2091+ return;
2092+ }
2093+ iforce->len = data;
2094+ return;
2095+ }
2096+
2097+ if (iforce->idx < iforce->len) {
2098+ iforce->csum += iforce->data[iforce->idx++] = data;
2099+ return;
2100+ }
2101+
2102+ if (iforce->idx == iforce->len) {
2103+ iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
2104+ iforce->pkt = 0;
2105+ iforce->id = 0;
2106+ iforce->len = 0;
2107+ iforce->idx = 0;
2108+ iforce->csum = 0;
2109+ }
2110+}
2111+
2112+static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
2113+{
2114+ struct iforce *iforce;
2115+ if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
2116+ return;
2117+
2118+ if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return;
2119+ memset(iforce, 0, sizeof(struct iforce));
2120+
2121+ iforce->bus = IFORCE_232;
2122+ iforce->serio = serio;
2123+ serio->private = iforce;
2124+
2125+ if (serio_open(serio, dev)) {
2126+ kfree(iforce);
2127+ return;
2128+ }
2129+
2130+ if (iforce_init_device(iforce)) {
2131+ serio_close(serio);
2132+ kfree(iforce);
2133+ return;
2134+ }
2135+}
2136+
2137+static void iforce_serio_disconnect(struct serio *serio)
2138+{
2139+ struct iforce* iforce = serio->private;
2140+
2141+ input_unregister_device(&iforce->dev);
2142+ serio_close(serio);
2143+ kfree(iforce);
2144+}
2145+
2146+struct serio_dev iforce_serio_dev = {
2147+ write_wakeup: iforce_serio_write_wakeup,
2148+ interrupt: iforce_serio_irq,
2149+ connect: iforce_serio_connect,
2150+ disconnect: iforce_serio_disconnect,
2151+};
2152diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/iforce-usb.c linux-modified/drivers/char/joystick/iforce/iforce-usb.c
2153--- linux-vanilla/drivers/char/joystick/iforce/iforce-usb.c Thu Jan 1 02:00:00 1970
2154+++ linux-modified/drivers/char/joystick/iforce/iforce-usb.c Mon Feb 17 21:28:41 2003
2155@@ -0,0 +1,211 @@
2156+ /*
2157+ * $Id$
2158+ *
2159+ * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
2160+ * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
2161+ *
2162+ * USB/RS232 I-Force joysticks and wheels.
2163+ */
2164+
2165+/*
2166+ * This program is free software; you can redistribute it and/or modify
2167+ * it under the terms of the GNU General Public License as published by
2168+ * the Free Software Foundation; either version 2 of the License, or
2169+ * (at your option) any later version.
2170+ *
2171+ * This program is distributed in the hope that it will be useful,
2172+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2173+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2174+ * GNU General Public License for more details.
2175+ *
2176+ * You should have received a copy of the GNU General Public License
2177+ * along with this program; if not, write to the Free Software
2178+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2179+ *
2180+ * Should you need to contact me, the author, you can do so either by
2181+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
2182+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
2183+ */
2184+
2185+#include "iforce.h"
2186+
2187+void iforce_usb_xmit(struct iforce *iforce)
2188+{
2189+ int n, c;
2190+ unsigned long flags;
2191+
2192+ spin_lock_irqsave(&iforce->xmit_lock, flags);
2193+
2194+ if (iforce->xmit.head == iforce->xmit.tail) {
2195+ clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
2196+ spin_unlock_irqrestore(&iforce->xmit_lock, flags);
2197+ return;
2198+ }
2199+
2200+ ((char *)iforce->out->transfer_buffer)[0] = iforce->xmit.buf[iforce->xmit.tail];
2201+ XMIT_INC(iforce->xmit.tail, 1);
2202+ n = iforce->xmit.buf[iforce->xmit.tail];
2203+ XMIT_INC(iforce->xmit.tail, 1);
2204+
2205+ iforce->out->transfer_buffer_length = n + 1;
2206+ iforce->out->dev = iforce->usbdev;
2207+
2208+ /* Copy rest of data then */
2209+ c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE);
2210+ if (n < c) c=n;
2211+
2212+ memcpy(iforce->out->transfer_buffer + 1,
2213+ &iforce->xmit.buf[iforce->xmit.tail],
2214+ c);
2215+ if (n != c) {
2216+ memcpy(iforce->out->transfer_buffer + 1 + c,
2217+ &iforce->xmit.buf[0],
2218+ n-c);
2219+ }
2220+ XMIT_INC(iforce->xmit.tail, n);
2221+
2222+ spin_unlock_irqrestore(&iforce->xmit_lock, flags);
2223+
2224+ if ( (n=usb_submit_urb(iforce->out)) ) {
2225+ printk(KERN_WARNING "iforce.c: iforce_usb_xmit: usb_submit_urb failed %d\n", n);
2226+ }
2227+}
2228+
2229+static void iforce_usb_irq(struct urb *urb)
2230+{
2231+ struct iforce *iforce = urb->context;
2232+ if (urb->status) return;
2233+ iforce_process_packet(iforce,
2234+ (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
2235+}
2236+
2237+static void iforce_usb_out(struct urb *urb)
2238+{
2239+ struct iforce *iforce = urb->context;
2240+
2241+ if (urb->status) {
2242+ printk(KERN_DEBUG "iforce_usb_out: urb->status %d, exiting", urb->status);
2243+ return;
2244+ }
2245+
2246+ iforce_usb_xmit(iforce);
2247+
2248+ if (waitqueue_active(&iforce->wait))
2249+ wake_up(&iforce->wait);
2250+}
2251+
2252+static void iforce_usb_ctrl(struct urb *urb)
2253+{
2254+ struct iforce *iforce = urb->context;
2255+ if (urb->status) return;
2256+ iforce->ecmd = 0xff00 | urb->actual_length;
2257+ if (waitqueue_active(&iforce->wait))
2258+ wake_up(&iforce->wait);
2259+}
2260+
2261+static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum,
2262+ const struct usb_device_id *id)
2263+{
2264+ struct usb_endpoint_descriptor *epirq, *epout;
2265+ struct iforce *iforce;
2266+
2267+ epirq = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
2268+ epout = dev->config[0].interface[ifnum].altsetting[0].endpoint + 1;
2269+
2270+ if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
2271+ goto fail;
2272+
2273+ memset(iforce, 0, sizeof(struct iforce));
2274+
2275+ if (!(iforce->irq = usb_alloc_urb(0))) {
2276+ goto fail;
2277+ }
2278+
2279+ if (!(iforce->out = usb_alloc_urb(0))) {
2280+ goto fail;
2281+ }
2282+
2283+ if (!(iforce->ctrl = usb_alloc_urb(0))) {
2284+ goto fail;
2285+ }
2286+
2287+ iforce->bus = IFORCE_USB;
2288+ iforce->usbdev = dev;
2289+
2290+ iforce->dr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
2291+ iforce->dr.wIndex = 0;
2292+ iforce->dr.wLength = 16;
2293+
2294+ usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
2295+ iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
2296+
2297+ usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
2298+ iforce + 1, 32, iforce_usb_out, iforce);
2299+
2300+ usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
2301+ (void*) &iforce->dr, iforce->edata, 16, iforce_usb_ctrl, iforce);
2302+
2303+ if (iforce_init_device(iforce)) goto fail;
2304+
2305+ return iforce;
2306+
2307+fail:
2308+ if (iforce) {
2309+ if (iforce->irq) usb_free_urb(iforce->irq);
2310+ if (iforce->out) usb_free_urb(iforce->out);
2311+ if (iforce->ctrl) usb_free_urb(iforce->ctrl);
2312+ kfree(iforce);
2313+ }
2314+
2315+ return NULL;
2316+}
2317+
2318+/* Called by iforce_delete() */
2319+void iforce_usb_delete(struct iforce* iforce)
2320+{
2321+ usb_unlink_urb(iforce->irq);
2322+ usb_unlink_urb(iforce->out);
2323+ usb_unlink_urb(iforce->ctrl);
2324+
2325+ usb_free_urb(iforce->irq);
2326+ usb_free_urb(iforce->out);
2327+ usb_free_urb(iforce->ctrl);
2328+}
2329+
2330+static void iforce_usb_disconnect(struct usb_device *dev, void *ptr)
2331+{
2332+ struct iforce *iforce = ptr;
2333+ int open = iforce->dev.handle->open;
2334+
2335+ iforce->usbdev = NULL;
2336+ input_unregister_device(&iforce->dev);
2337+
2338+ if (!open) {
2339+ iforce_delete_device(iforce);
2340+ kfree(iforce);
2341+ }
2342+}
2343+
2344+static struct usb_device_id iforce_usb_ids [] = {
2345+ { USB_DEVICE(0x044f, 0xa01c) }, /* Thrustmaster Motor Sport GT */
2346+ { USB_DEVICE(0x046d, 0xc281) }, /* Logitech WingMan Force */
2347+ { USB_DEVICE(0x046d, 0xc291) }, /* Logitech WingMan Formula Force */
2348+ { USB_DEVICE(0x05ef, 0x020a) }, /* AVB Top Shot Pegasus */
2349+ { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */
2350+ { USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */
2351+ { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */
2352+ { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */
2353+ { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */
2354+ { USB_DEVICE(0x06a3, 0xff12) }, /* Saitek Cyborgforce 3d */
2355+ { } /* Terminating entry */
2356+};
2357+
2358+MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
2359+
2360+struct usb_driver iforce_usb_driver = {
2361+// owner: THIS_MODULE,
2362+ name: "iforce",
2363+ probe: iforce_usb_probe,
2364+ disconnect: iforce_usb_disconnect,
2365+ id_table: iforce_usb_ids,
2366+};
2367diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce/iforce.h linux-modified/drivers/char/joystick/iforce/iforce.h
2368--- linux-vanilla/drivers/char/joystick/iforce/iforce.h Thu Jan 1 02:00:00 1970
2369+++ linux-modified/drivers/char/joystick/iforce/iforce.h Sun Mar 9 16:58:46 2003
2370@@ -0,0 +1,184 @@
2371+/*
2372+ * $Id$
2373+ *
2374+ * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
2375+ * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
2376+ *
2377+ * USB/RS232 I-Force joysticks and wheels.
2378+ */
2379+
2380+/*
2381+ * This program is free software; you can redistribute it and/or modify
2382+ * it under the terms of the GNU General Public License as published by
2383+ * the Free Software Foundation; either version 2 of the License, or
2384+ * (at your option) any later version.
2385+ *
2386+ * This program is distributed in the hope that it will be useful,
2387+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2388+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2389+ * GNU General Public License for more details.
2390+ *
2391+ * You should have received a copy of the GNU General Public License
2392+ * along with this program; if not, write to the Free Software
2393+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2394+ *
2395+ * Should you need to contact me, the author, you can do so either by
2396+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
2397+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
2398+ */
2399+
2400+#include <linux/kernel.h>
2401+#include <linux/slab.h>
2402+#include <linux/input.h>
2403+#include <linux/module.h>
2404+#include <linux/init.h>
2405+#include <linux/spinlock.h>
2406+#include <linux/usb.h>
2407+#include <linux/serio.h>
2408+#include <linux/config.h>
2409+#include <linux/circ_buf.h>
2410+#include <asm/semaphore.h>
2411+
2412+/* FF: This module provides arbitrary resource management routines.
2413+ * I use it to manage the device's memory.
2414+ * Despite the name of this module, I am *not* going to access the ioports.
2415+ */
2416+#include <linux/ioport.h>
2417+
2418+#define IFORCE_MAX_LENGTH 16
2419+
2420+#define IFORCE_232 1
2421+#define IFORCE_USB 2
2422+
2423+#define FALSE 0
2424+#define TRUE 1
2425+
2426+#define FF_EFFECTS_MAX 32
2427+
2428+/* Each force feedback effect is made of one core effect, which can be
2429+ * associated to at most to effect modifiers
2430+ */
2431+#define FF_MOD1_IS_USED 0
2432+#define FF_MOD2_IS_USED 1
2433+#define FF_CORE_IS_USED 2
2434+#define FF_CORE_IS_PLAYED 3 /* Effect is currently being played */
2435+#define FF_CORE_SHOULD_PLAY 4 /* User wants the effect to be played */
2436+#define FF_CORE_UPDATE 5 /* Effect is being updated */
2437+#define FF_MODCORE_MAX 5
2438+
2439+struct iforce_core_effect {
2440+ /* Information about where modifiers are stored in the device's memory */
2441+ struct resource mod1_chunk;
2442+ struct resource mod2_chunk;
2443+ unsigned long flags[NBITS(FF_MODCORE_MAX)];
2444+ pid_t owner;
2445+ /* Used to keep track of parameters of an effect. They are needed
2446+ * to know what parts of an effect changed in an update operation.
2447+ * We try to send only parameter packets if possible, as sending
2448+ * effect parameter requires the effect to be stoped and restarted
2449+ */
2450+ struct ff_effect effect;
2451+};
2452+
2453+#define FF_CMD_EFFECT 0x010e
2454+#define FF_CMD_ENVELOPE 0x0208
2455+#define FF_CMD_MAGNITUDE 0x0303
2456+#define FF_CMD_PERIOD 0x0407
2457+#define FF_CMD_CONDITION 0x050a
2458+
2459+#define FF_CMD_AUTOCENTER 0x4002
2460+#define FF_CMD_PLAY 0x4103
2461+#define FF_CMD_ENABLE 0x4201
2462+#define FF_CMD_GAIN 0x4301
2463+
2464+#define FF_CMD_QUERY 0xff01
2465+
2466+/* Buffer for async write */
2467+#define XMIT_SIZE 256
2468+#define XMIT_INC(var, n) (var)+=n; (var)&= XMIT_SIZE -1
2469+/* iforce::xmit_flags */
2470+#define IFORCE_XMIT_RUNNING 0
2471+#define IFORCE_XMIT_AGAIN 1
2472+
2473+struct iforce_device {
2474+ u16 idvendor;
2475+ u16 idproduct;
2476+ char *name;
2477+ signed short *btn;
2478+ signed short *abs;
2479+ signed short *ff;
2480+};
2481+
2482+struct iforce {
2483+ struct input_dev dev; /* Input device interface */
2484+ struct iforce_device *type;
2485+ int bus;
2486+
2487+ unsigned char data[IFORCE_MAX_LENGTH];
2488+ unsigned char edata[IFORCE_MAX_LENGTH];
2489+ u16 ecmd;
2490+ u16 expect_packet;
2491+
2492+#ifdef CONFIG_JOYSTICK_IFORCE_232
2493+ struct serio *serio; /* RS232 transfer */
2494+ int idx, pkt, len, id;
2495+ unsigned char csum;
2496+#endif
2497+#ifdef CONFIG_JOYSTICK_IFORCE_USB
2498+ struct usb_device *usbdev; /* USB transfer */
2499+ struct urb *irq, *out, *ctrl;
2500+ struct usb_ctrlrequest dr;
2501+#endif
2502+ spinlock_t xmit_lock;
2503+ /* Buffer used for asynchronous sending of bytes to the device */
2504+ struct circ_buf xmit;
2505+ unsigned char xmit_data[XMIT_SIZE];
2506+ long xmit_flags[1];
2507+
2508+ /* Force Feedback */
2509+ wait_queue_head_t wait;
2510+ struct resource device_memory;
2511+ struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
2512+ struct semaphore mem_mutex;
2513+};
2514+
2515+/* Get hi and low bytes of a 16-bits int */
2516+#define HI(a) ((unsigned char)((a) >> 8))
2517+#define LO(a) ((unsigned char)((a) & 0xff))
2518+
2519+/* For many parameters, it seems that 0x80 is a special value that should
2520+ * be avoided. Instead, we replace this value by 0x7f
2521+ */
2522+#define HIFIX80(a) ((unsigned char)(((a)<0? (a)+255 : (a))>>8))
2523+
2524+/* Encode a time value */
2525+#define TIME_SCALE(a) (a)
2526+
2527+
2528+/* Public functions */
2529+/* iforce-serio.c */
2530+void iforce_serial_xmit(struct iforce *iforce);
2531+
2532+/* iforce-usb.c */
2533+void iforce_usb_xmit(struct iforce *iforce);
2534+void iforce_usb_delete(struct iforce *iforce);
2535+
2536+/* iforce-main.c */
2537+int iforce_init_device(struct iforce *iforce);
2538+void iforce_delete_device(struct iforce *iforce);
2539+
2540+/* iforce-packets.c */
2541+int iforce_control_playback(struct iforce*, u16 id, unsigned int);
2542+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
2543+int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
2544+void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
2545+int iforce_get_id_packet(struct iforce *iforce, char *packet);
2546+
2547+/* iforce-ff.c */
2548+int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update);
2549+int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update);
2550+int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update);
2551+
2552+/* Public variables */
2553+extern struct serio_dev iforce_serio_dev;
2554+extern struct usb_driver iforce_usb_driver;
2555diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/iforce.c linux-modified/drivers/char/joystick/iforce.c
2556--- linux-vanilla/drivers/char/joystick/iforce.c Mon Feb 3 20:32:38 2003
2557+++ linux-modified/drivers/char/joystick/iforce.c Thu Jan 1 02:00:00 1970
2558@@ -1,1199 +0,0 @@
2559-/*
2560- * $Id$
2561- *
2562- * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
2563- * Copyright (c) 2001 Johann Deneux <deneux@ifrance.com>
2564- *
2565- * USB/RS232 I-Force joysticks and wheels.
2566- *
2567- * Sponsored by SuSE
2568- */
2569-
2570-/*
2571- * This program is free software; you can redistribute it and/or modify
2572- * it under the terms of the GNU General Public License as published by
2573- * the Free Software Foundation; either version 2 of the License, or
2574- * (at your option) any later version.
2575- *
2576- * This program is distributed in the hope that it will be useful,
2577- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2578- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2579- * GNU General Public License for more details.
2580- *
2581- * You should have received a copy of the GNU General Public License
2582- * along with this program; if not, write to the Free Software
2583- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2584- *
2585- * Should you need to contact me, the author, you can do so either by
2586- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
2587- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
2588- */
2589-
2590-#include <linux/kernel.h>
2591-#include <linux/slab.h>
2592-#include <linux/input.h>
2593-#include <linux/module.h>
2594-#include <linux/init.h>
2595-#include <linux/spinlock.h>
2596-#include <linux/usb.h>
2597-#include <linux/serio.h>
2598-#include <linux/config.h>
2599-
2600-/* FF: This module provides arbitrary resource management routines.
2601- * I use it to manage the device's memory.
2602- * Despite the name of this module, I am *not* going to access the ioports.
2603- */
2604-#include <linux/ioport.h>
2605-
2606-MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>, Johann Deneux <deneux@ifrance.com>");
2607-MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
2608-MODULE_LICENSE("GPL");
2609-
2610-#define IFORCE_MAX_LENGTH 16
2611-
2612-#if defined(CONFIG_INPUT_IFORCE_232) || defined(CONFIG_INPUT_IFORCE_232_MODULE)
2613-#define IFORCE_232 1
2614-#endif
2615-#if defined(CONFIG_INPUT_IFORCE_USB) || defined(CONFIG_INPUT_IFORCE_USB_MODULE)
2616-#define IFORCE_USB 2
2617-#endif
2618-
2619-#define FF_EFFECTS_MAX 32
2620-
2621-/* Each force feedback effect is made of one core effect, which can be
2622- * associated to at most to effect modifiers
2623- */
2624-#define FF_MOD1_IS_USED 0
2625-#define FF_MOD2_IS_USED 1
2626-#define FF_CORE_IS_USED 2
2627-#define FF_CORE_IS_PLAYED 3
2628-#define FF_MODCORE_MAX 3
2629-
2630-struct iforce_core_effect {
2631- /* Information about where modifiers are stored in the device's memory */
2632- struct resource mod1_chunk;
2633- struct resource mod2_chunk;
2634- unsigned long flags[NBITS(FF_MODCORE_MAX)];
2635-};
2636-
2637-#define FF_CMD_EFFECT 0x010e
2638-#define FF_CMD_SHAPE 0x0208
2639-#define FF_CMD_MAGNITUDE 0x0303
2640-#define FF_CMD_PERIOD 0x0407
2641-#define FF_CMD_INTERACT 0x050a
2642-
2643-#define FF_CMD_AUTOCENTER 0x4002
2644-#define FF_CMD_PLAY 0x4103
2645-#define FF_CMD_ENABLE 0x4201
2646-#define FF_CMD_GAIN 0x4301
2647-
2648-#define FF_CMD_QUERY 0xff01
2649-
2650-static signed short btn_joystick[] = { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
2651- BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, BTN_DEAD, -1 };
2652-static signed short btn_wheel[] = { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
2653- BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
2654-static signed short abs_joystick[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
2655-static signed short abs_wheel[] = { ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, -1 };
2656-static signed short ff_iforce[] = { FF_PERIODIC, FF_CONSTANT, FF_SPRING, FF_FRICTION,
2657- FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP, FF_SAW_DOWN, FF_GAIN, FF_AUTOCENTER, -1 };
2658-
2659-static struct iforce_device {
2660- u16 idvendor;
2661- u16 idproduct;
2662- char *name;
2663- signed short *btn;
2664- signed short *abs;
2665- signed short *ff;
2666-} iforce_device[] = {
2667- { 0x046d, 0xc281, "Logitech WingMan Force", btn_joystick, abs_joystick, ff_iforce },
2668- { 0x046d, 0xc291, "Logitech WingMan Formula Force", btn_wheel, abs_wheel, ff_iforce },
2669- { 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_joystick, abs_joystick, ff_iforce },
2670- { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_wheel, abs_wheel, ff_iforce },
2671- { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce },
2672- { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce }
2673-};
2674-
2675-struct iforce {
2676- struct input_dev dev; /* Input device interface */
2677- struct iforce_device *type;
2678- char name[64];
2679- int open;
2680- int bus;
2681-
2682- unsigned char data[IFORCE_MAX_LENGTH];
2683- unsigned char edata[IFORCE_MAX_LENGTH];
2684- u16 ecmd;
2685- u16 expect_packet;
2686-
2687-#ifdef IFORCE_232
2688- struct serio *serio; /* RS232 transfer */
2689- int idx, pkt, len, id;
2690- unsigned char csum;
2691-#endif
2692-#ifdef IFORCE_USB
2693- struct usb_device *usbdev; /* USB transfer */
2694- struct urb irq, out, ctrl;
2695- struct usb_ctrlrequest dr;
2696-#endif
2697- /* Force Feedback */
2698- wait_queue_head_t wait;
2699- struct resource device_memory;
2700- struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
2701-};
2702-
2703-static struct {
2704- __s32 x;
2705- __s32 y;
2706-} iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
2707-
2708-/* Get hi and low bytes of a 16-bits int */
2709-#define HI(a) ((unsigned char)((a) >> 8))
2710-#define LO(a) ((unsigned char)((a) & 0xff))
2711-
2712-/* Encode a time value */
2713-#define TIME_SCALE(a) ((a) == 0xffff ? 0xffff : (a) * 1000 / 256)
2714-
2715-static void dump_packet(char *msg, u16 cmd, unsigned char *data)
2716-{
2717- int i;
2718-
2719- printk(KERN_DEBUG "iforce.c: %s ( cmd = %04x, data = ", msg, cmd);
2720- for (i = 0; i < LO(cmd); i++)
2721- printk("%02x ", data[i]);
2722- printk(")\n");
2723-}
2724-
2725-/*
2726- * Send a packet of bytes to the device
2727- */
2728-static void send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
2729-{
2730- switch (iforce->bus) {
2731-
2732-#ifdef IFORCE_232
2733- case IFORCE_232: {
2734-
2735- int i;
2736- unsigned char csum = 0x2b ^ HI(cmd) ^ LO(cmd);
2737-
2738- serio_write(iforce->serio, 0x2b);
2739- serio_write(iforce->serio, HI(cmd));
2740- serio_write(iforce->serio, LO(cmd));
2741-
2742- for (i = 0; i < LO(cmd); i++) {
2743- serio_write(iforce->serio, data[i]);
2744- csum = csum ^ data[i];
2745- }
2746-
2747- serio_write(iforce->serio, csum);
2748- return;
2749- }
2750-#endif
2751-#ifdef IFORCE_USB
2752- case IFORCE_USB: {
2753-
2754- DECLARE_WAITQUEUE(wait, current);
2755- int timeout = HZ; /* 1 second */
2756-
2757- memcpy(iforce->out.transfer_buffer + 1, data, LO(cmd));
2758- ((char*)iforce->out.transfer_buffer)[0] = HI(cmd);
2759- iforce->out.transfer_buffer_length = LO(cmd) + 2;
2760- iforce->out.dev = iforce->usbdev;
2761-
2762- set_current_state(TASK_INTERRUPTIBLE);
2763- add_wait_queue(&iforce->wait, &wait);
2764-
2765- if (usb_submit_urb(&iforce->out)) {
2766- set_current_state(TASK_RUNNING);
2767- remove_wait_queue(&iforce->wait, &wait);
2768- return;
2769- }
2770-
2771- while (timeout && iforce->out.status == -EINPROGRESS)
2772- timeout = schedule_timeout(timeout);
2773-
2774- set_current_state(TASK_RUNNING);
2775- remove_wait_queue(&iforce->wait, &wait);
2776-
2777- if (!timeout)
2778- usb_unlink_urb(&iforce->out);
2779-
2780- return;
2781- }
2782-#endif
2783- }
2784-}
2785-
2786-static void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
2787-{
2788- struct input_dev *dev = &iforce->dev;
2789- int i;
2790-
2791-#ifdef IFORCE_232
2792- if (HI(iforce->expect_packet) == HI(cmd)) {
2793- iforce->expect_packet = 0;
2794- iforce->ecmd = cmd;
2795- memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
2796- if (waitqueue_active(&iforce->wait))
2797- wake_up(&iforce->wait);
2798- }
2799-#endif
2800-
2801- if (!iforce->type)
2802- return;
2803-
2804- switch (HI(cmd)) {
2805-
2806- case 0x01: /* joystick position data */
2807- case 0x03: /* wheel position data */
2808-
2809- if (HI(cmd) == 1) {
2810- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
2811- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
2812- input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
2813- } else {
2814- input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
2815- input_report_abs(dev, ABS_GAS, 255 - data[2]);
2816- input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
2817- }
2818-
2819- input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
2820- input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y);
2821-
2822- for (i = 0; iforce->type->btn[i] >= 0; i++)
2823- input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7)));
2824-
2825- break;
2826-
2827- case 0x02: /* status report */
2828-
2829- input_report_key(dev, BTN_DEAD, data[0] & 0x02);
2830- break;
2831- }
2832-}
2833-
2834-static int get_id_packet(struct iforce *iforce, char *packet)
2835-{
2836- DECLARE_WAITQUEUE(wait, current);
2837- int timeout = HZ; /* 1 second */
2838-
2839- switch (iforce->bus) {
2840-
2841-#ifdef IFORCE_USB
2842- case IFORCE_USB:
2843-
2844- iforce->dr.bRequest = packet[0];
2845- iforce->ctrl.dev = iforce->usbdev;
2846-
2847- set_current_state(TASK_INTERRUPTIBLE);
2848- add_wait_queue(&iforce->wait, &wait);
2849-
2850- if (usb_submit_urb(&iforce->ctrl)) {
2851- set_current_state(TASK_RUNNING);
2852- remove_wait_queue(&iforce->wait, &wait);
2853- return -1;
2854- }
2855-
2856- while (timeout && iforce->ctrl.status == -EINPROGRESS)
2857- timeout = schedule_timeout(timeout);
2858-
2859- set_current_state(TASK_RUNNING);
2860- remove_wait_queue(&iforce->wait, &wait);
2861-
2862- if (!timeout) {
2863- usb_unlink_urb(&iforce->ctrl);
2864- return -1;
2865- }
2866-
2867- break;
2868-#endif
2869-#ifdef IFORCE_232
2870- case IFORCE_232:
2871-
2872- iforce->expect_packet = FF_CMD_QUERY;
2873- send_packet(iforce, FF_CMD_QUERY, packet);
2874-
2875- set_current_state(TASK_INTERRUPTIBLE);
2876- add_wait_queue(&iforce->wait, &wait);
2877-
2878- while (timeout && iforce->expect_packet)
2879- timeout = schedule_timeout(timeout);
2880-
2881- set_current_state(TASK_RUNNING);
2882- remove_wait_queue(&iforce->wait, &wait);
2883-
2884- if (!timeout) {
2885- iforce->expect_packet = 0;
2886- return -1;
2887- }
2888-
2889- break;
2890-#endif
2891- }
2892-
2893- return -(iforce->edata[0] != packet[0]);
2894-}
2895-
2896-static int iforce_open(struct input_dev *dev)
2897-{
2898- struct iforce *iforce = dev->private;
2899-
2900- switch (iforce->bus) {
2901-#ifdef IFORCE_USB
2902- case IFORCE_USB:
2903- if (iforce->open++)
2904- break;
2905- iforce->irq.dev = iforce->usbdev;
2906- if (usb_submit_urb(&iforce->irq))
2907- return -EIO;
2908- break;
2909-#endif
2910- }
2911- return 0;
2912-}
2913-
2914-static void iforce_close(struct input_dev *dev)
2915-{
2916- struct iforce *iforce = dev->private;
2917-
2918- switch (iforce->bus) {
2919-#ifdef IFORCE_USB
2920- case IFORCE_USB:
2921- if (!--iforce->open)
2922- usb_unlink_urb(&iforce->irq);
2923- break;
2924-#endif
2925- }
2926-}
2927-
2928-/*
2929- * Start or stop playing an effect
2930- */
2931-
2932-static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
2933-{
2934- struct iforce* iforce = (struct iforce*)(dev->private);
2935- unsigned char data[3];
2936-
2937- printk(KERN_DEBUG "iforce.c: input_event(type = %d, code = %d, value = %d)\n", type, code, value);
2938-
2939- if (type != EV_FF)
2940- return -1;
2941-
2942- switch (code) {
2943-
2944- case FF_GAIN:
2945-
2946- data[0] = value >> 9;
2947- send_packet(iforce, FF_CMD_GAIN, data);
2948-
2949- return 0;
2950-
2951- case FF_AUTOCENTER:
2952-
2953- data[0] = 0x03;
2954- data[1] = value >> 9;
2955- send_packet(iforce, FF_CMD_AUTOCENTER, data);
2956-
2957- data[0] = 0x04;
2958- data[1] = 0x01;
2959- send_packet(iforce, FF_CMD_AUTOCENTER, data);
2960-
2961- return 0;
2962-
2963- default: /* Play an effect */
2964-
2965- if (code >= iforce->dev.ff_effects_max)
2966- return -1;
2967-
2968- data[0] = LO(code);
2969- data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0;
2970- data[2] = LO(value);
2971- send_packet(iforce, FF_CMD_PLAY, data);
2972-
2973- return 0;
2974- }
2975-
2976- return -1;
2977-}
2978-
2979-/*
2980- * Set the magnitude of a constant force effect
2981- * Return error code
2982- *
2983- * Note: caller must ensure exclusive access to device
2984- */
2985-
2986-static int make_magnitude_modifier(struct iforce* iforce,
2987- struct resource* mod_chunk, __s16 level)
2988-{
2989- unsigned char data[3];
2990-
2991- if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
2992- iforce->device_memory.start, iforce->device_memory.end, 2L,
2993- NULL, NULL)) {
2994- return -ENOMEM;
2995- }
2996-
2997- data[0] = LO(mod_chunk->start);
2998- data[1] = HI(mod_chunk->start);
2999- data[2] = HI(level);
3000-
3001- send_packet(iforce, FF_CMD_MAGNITUDE, data);
3002-
3003- return 0;
3004-}
3005-
3006-/*
3007- * Upload the component of an effect dealing with the period, phase and magnitude
3008- */
3009-
3010-static int make_period_modifier(struct iforce* iforce, struct resource* mod_chunk,
3011- __s16 magnitude, __s16 offset, u16 period, u16 phase)
3012-{
3013- unsigned char data[7];
3014-
3015- period = TIME_SCALE(period);
3016-
3017- if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
3018- iforce->device_memory.start, iforce->device_memory.end, 2L,
3019- NULL, NULL)) {
3020- return -ENOMEM;
3021- }
3022-
3023- data[0] = LO(mod_chunk->start);
3024- data[1] = HI(mod_chunk->start);
3025-
3026- data[2] = HI(magnitude);
3027- data[3] = HI(offset);
3028- data[4] = HI(phase);
3029-
3030- data[5] = LO(period);
3031- data[6] = HI(period);
3032-
3033- send_packet(iforce, FF_CMD_PERIOD, data);
3034-
3035- return 0;
3036-}
3037-
3038-/*
3039- * Uploads the part of an effect setting the shape of the force
3040- */
3041-
3042-static int make_shape_modifier(struct iforce* iforce, struct resource* mod_chunk,
3043- u16 attack_duration, __s16 initial_level,
3044- u16 fade_duration, __s16 final_level)
3045-{
3046- unsigned char data[8];
3047-
3048- attack_duration = TIME_SCALE(attack_duration);
3049- fade_duration = TIME_SCALE(fade_duration);
3050-
3051- if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
3052- iforce->device_memory.start, iforce->device_memory.end, 2L,
3053- NULL, NULL)) {
3054- return -ENOMEM;
3055- }
3056-
3057- data[0] = LO(mod_chunk->start);
3058- data[1] = HI(mod_chunk->start);
3059-
3060- data[2] = LO(attack_duration);
3061- data[3] = HI(attack_duration);
3062- data[4] = HI(initial_level);
3063-
3064- data[5] = LO(fade_duration);
3065- data[6] = HI(fade_duration);
3066- data[7] = HI(final_level);
3067-
3068- send_packet(iforce, FF_CMD_SHAPE, data);
3069-
3070- return 0;
3071-}
3072-
3073-/*
3074- * Component of spring, friction, inertia... effects
3075- */
3076-
3077-static int make_interactive_modifier(struct iforce* iforce,
3078- struct resource* mod_chunk,
3079- __s16 rsat, __s16 lsat, __s16 rk, __s16 lk, u16 db, __s16 center)
3080-{
3081- unsigned char data[10];
3082-
3083- if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
3084- iforce->device_memory.start, iforce->device_memory.end, 2L,
3085- NULL, NULL)) {
3086- return -ENOMEM;
3087- }
3088-
3089- data[0] = LO(mod_chunk->start);
3090- data[1] = HI(mod_chunk->start);
3091-
3092- data[2] = HI(rk);
3093- data[3] = HI(lk);
3094-
3095- data[4] = LO(center);
3096- data[5] = HI(center);
3097-
3098- data[6] = LO(db);
3099- data[7] = HI(db);
3100-
3101- data[8] = HI(rsat);
3102- data[9] = HI(lsat);
3103-
3104- send_packet(iforce, FF_CMD_INTERACT, data);
3105-
3106- return 0;
3107-}
3108-
3109-static unsigned char find_button(struct iforce *iforce, signed short button)
3110-{
3111- int i;
3112- for (i = 1; iforce->type->btn[i] >= 0; i++)
3113- if (iforce->type->btn[i] == button)
3114- return i + 1;
3115- return 0;
3116-}
3117-
3118-/*
3119- * Send the part common to all effects to the device
3120- */
3121-
3122-static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
3123- u8 effect_type, u8 axes, u16 duration, u16 delay, u16 button,
3124- u16 interval, u16 direction)
3125-{
3126- unsigned char data[14];
3127-
3128- duration = TIME_SCALE(duration);
3129- delay = TIME_SCALE(delay);
3130- interval = TIME_SCALE(interval);
3131-
3132- data[0] = LO(id);
3133- data[1] = effect_type;
3134- data[2] = LO(axes) | find_button(iforce, button);
3135-
3136- data[3] = LO(duration);
3137- data[4] = HI(duration);
3138-
3139- data[5] = HI(direction);
3140-
3141- data[6] = LO(interval);
3142- data[7] = HI(interval);
3143-
3144- data[8] = LO(mod_id1);
3145- data[9] = HI(mod_id1);
3146- data[10] = LO(mod_id2);
3147- data[11] = HI(mod_id2);
3148-
3149- data[12] = LO(delay);
3150- data[13] = HI(delay);
3151-
3152- send_packet(iforce, FF_CMD_EFFECT, data);
3153-
3154- return 0;
3155-}
3156-
3157-/*
3158- * Upload a periodic effect to the device
3159- */
3160-
3161-static int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect)
3162-{
3163- u8 wave_code;
3164- int core_id = effect->id;
3165- struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
3166- struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
3167- struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
3168- int err = 0;
3169-
3170- err = make_period_modifier(iforce, mod1_chunk,
3171- effect->u.periodic.magnitude, effect->u.periodic.offset,
3172- effect->u.periodic.period, effect->u.periodic.phase);
3173- if (err) return err;
3174- set_bit(FF_MOD1_IS_USED, core_effect->flags);
3175-
3176- err = make_shape_modifier(iforce, mod2_chunk,
3177- effect->u.periodic.shape.attack_length,
3178- effect->u.periodic.shape.attack_level,
3179- effect->u.periodic.shape.fade_length,
3180- effect->u.periodic.shape.fade_level);
3181- if (err) return err;
3182- set_bit(FF_MOD2_IS_USED, core_effect->flags);
3183-
3184- switch (effect->u.periodic.waveform) {
3185- case FF_SQUARE: wave_code = 0x20; break;
3186- case FF_TRIANGLE: wave_code = 0x21; break;
3187- case FF_SINE: wave_code = 0x22; break;
3188- case FF_SAW_UP: wave_code = 0x23; break;
3189- case FF_SAW_DOWN: wave_code = 0x24; break;
3190- default: wave_code = 0x20; break;
3191- }
3192-
3193- err = make_core(iforce, effect->id,
3194- mod1_chunk->start,
3195- mod2_chunk->start,
3196- wave_code,
3197- 0x20,
3198- effect->replay.length,
3199- effect->replay.delay,
3200- effect->trigger.button,
3201- effect->trigger.interval,
3202- effect->u.periodic.direction);
3203-
3204- return err;
3205-}
3206-
3207-/*
3208- * Upload a constant force effect
3209- */
3210-static int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect)
3211-{
3212- int core_id = effect->id;
3213- struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
3214- struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
3215- struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
3216- int err = 0;
3217-
3218- printk(KERN_DEBUG "iforce.c: make constant effect\n");
3219-
3220- err = make_magnitude_modifier(iforce, mod1_chunk, effect->u.constant.level);
3221- if (err) return err;
3222- set_bit(FF_MOD1_IS_USED, core_effect->flags);
3223-
3224- err = make_shape_modifier(iforce, mod2_chunk,
3225- effect->u.constant.shape.attack_length,
3226- effect->u.constant.shape.attack_level,
3227- effect->u.constant.shape.fade_length,
3228- effect->u.constant.shape.fade_level);
3229- if (err) return err;
3230- set_bit(FF_MOD2_IS_USED, core_effect->flags);
3231-
3232- err = make_core(iforce, effect->id,
3233- mod1_chunk->start,
3234- mod2_chunk->start,
3235- 0x00,
3236- 0x20,
3237- effect->replay.length,
3238- effect->replay.delay,
3239- effect->trigger.button,
3240- effect->trigger.interval,
3241- effect->u.constant.direction);
3242-
3243- return err;
3244-}
3245-
3246-/*
3247- * Upload an interactive effect. Those are for example friction, inertia, springs...
3248- */
3249-static int iforce_upload_interactive(struct iforce* iforce, struct ff_effect* effect)
3250-{
3251- int core_id = effect->id;
3252- struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
3253- struct resource* mod_chunk = &(core_effect->mod1_chunk);
3254- u8 type, axes;
3255- u16 mod1, mod2, direction;
3256- int err = 0;
3257-
3258- printk(KERN_DEBUG "iforce.c: make interactive effect\n");
3259-
3260- switch (effect->type) {
3261- case FF_SPRING: type = 0x40; break;
3262- case FF_FRICTION: type = 0x41; break;
3263- default: return -1;
3264- }
3265-
3266- err = make_interactive_modifier(iforce, mod_chunk,
3267- effect->u.interactive.right_saturation,
3268- effect->u.interactive.left_saturation,
3269- effect->u.interactive.right_coeff,
3270- effect->u.interactive.left_coeff,
3271- effect->u.interactive.deadband,
3272- effect->u.interactive.center);
3273- if (err) return err;
3274- set_bit(FF_MOD1_IS_USED, core_effect->flags);
3275-
3276- switch ((test_bit(ABS_X, &effect->u.interactive.axis) ||
3277- test_bit(ABS_WHEEL, &effect->u.interactive.axis)) |
3278- (!!test_bit(ABS_Y, &effect->u.interactive.axis) << 1)) {
3279-
3280- case 0: /* Only one axis, choose orientation */
3281- mod1 = mod_chunk->start;
3282- mod2 = 0xffff;
3283- direction = effect->u.interactive.direction;
3284- axes = 0x20;
3285- break;
3286-
3287- case 1: /* Only X axis */
3288- mod1 = mod_chunk->start;
3289- mod2 = 0xffff;
3290- direction = 0x5a00;
3291- axes = 0x40;
3292- break;
3293-
3294- case 2: /* Only Y axis */
3295- mod1 = 0xffff;
3296- mod2 = mod_chunk->start;
3297- direction = 0xb400;
3298- axes = 0x80;
3299- break;
3300-
3301- case 3: /* Both X and Y axes */
3302- /* TODO: same setting for both axes is not mandatory */
3303- mod1 = mod_chunk->start;
3304- mod2 = mod_chunk->start;
3305- direction = 0x6000;
3306- axes = 0xc0;
3307- break;
3308-
3309- default:
3310- return -1;
3311- }
3312-
3313- err = make_core(iforce, effect->id,
3314- mod1, mod2,
3315- type, axes,
3316- effect->replay.length, effect->replay.delay,
3317- effect->trigger.button, effect->trigger.interval,
3318- direction);
3319-
3320- return err;
3321-}
3322-
3323-/*
3324- * Function called when an ioctl is performed on the event dev entry.
3325- * It uploads an effect to the device
3326- */
3327-static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
3328-{
3329- struct iforce* iforce = (struct iforce*)(dev->private);
3330- int id;
3331-
3332- printk(KERN_DEBUG "iforce.c: upload effect\n");
3333-
3334-/*
3335- * Get a free id
3336- */
3337-
3338- for (id=0; id < FF_EFFECTS_MAX; ++id)
3339- if (!test_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
3340-
3341- if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
3342- return -ENOMEM;
3343-
3344- effect->id = id;
3345- set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags);
3346-
3347-/*
3348- * Upload the effect
3349- */
3350-
3351- switch (effect->type) {
3352-
3353- case FF_PERIODIC:
3354- return iforce_upload_periodic(iforce, effect);
3355-
3356- case FF_CONSTANT:
3357- return iforce_upload_constant(iforce, effect);
3358-
3359- case FF_SPRING:
3360- case FF_FRICTION:
3361- return iforce_upload_interactive(iforce, effect);
3362-
3363- default:
3364- return -1;
3365- }
3366-}
3367-
3368-/*
3369- * Erases an effect: it frees the effect id and mark as unused the memory
3370- * allocated for the parameters
3371- */
3372-static int iforce_erase_effect(struct input_dev *dev, int effect_id)
3373-{
3374- struct iforce* iforce = (struct iforce*)(dev->private);
3375- int err = 0;
3376- struct iforce_core_effect* core_effect;
3377-
3378- printk(KERN_DEBUG "iforce.c: erase effect %d\n", effect_id);
3379-
3380- if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
3381- return -EINVAL;
3382-
3383- core_effect = iforce->core_effects + effect_id;
3384-
3385- if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
3386- err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk));
3387-
3388- if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
3389- err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk));
3390-
3391- /*TODO: remember to change that if more FF_MOD* bits are added */
3392- core_effect->flags[0] = 0;
3393-
3394- return err;
3395-}
3396-static int iforce_init_device(struct iforce *iforce)
3397-{
3398- unsigned char c[] = "CEOV";
3399- int i;
3400-
3401- init_waitqueue_head(&iforce->wait);
3402- iforce->dev.ff_effects_max = 10;
3403-
3404-/*
3405- * Input device fields.
3406- */
3407-
3408- iforce->dev.idbus = BUS_USB;
3409- iforce->dev.private = iforce;
3410- iforce->dev.name = iforce->name;
3411- iforce->dev.open = iforce_open;
3412- iforce->dev.close = iforce_close;
3413- iforce->dev.event = iforce_input_event;
3414- iforce->dev.upload_effect = iforce_upload_effect;
3415- iforce->dev.erase_effect = iforce_erase_effect;
3416-
3417-/*
3418- * On-device memory allocation.
3419- */
3420-
3421- iforce->device_memory.name = "I-Force device effect memory";
3422- iforce->device_memory.start = 0;
3423- iforce->device_memory.end = 200;
3424- iforce->device_memory.flags = IORESOURCE_MEM;
3425- iforce->device_memory.parent = NULL;
3426- iforce->device_memory.child = NULL;
3427- iforce->device_memory.sibling = NULL;
3428-
3429-/*
3430- * Wait until device ready - until it sends its first response.
3431- */
3432-
3433- for (i = 0; i < 20; i++)
3434- if (!get_id_packet(iforce, "O"))
3435- break;
3436-
3437- if (i == 20) { /* 5 seconds */
3438- printk(KERN_ERR "iforce.c: Timeout waiting for response from device.\n");
3439- iforce_close(&iforce->dev);
3440- return -1;
3441- }
3442-
3443-/*
3444- * Get device info.
3445- */
3446-
3447- if (!get_id_packet(iforce, "M"))
3448- iforce->dev.idvendor = (iforce->edata[2] << 8) | iforce->edata[1];
3449- if (!get_id_packet(iforce, "P"))
3450- iforce->dev.idproduct = (iforce->edata[2] << 8) | iforce->edata[1];
3451- if (!get_id_packet(iforce, "B"))
3452- iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
3453- if (!get_id_packet(iforce, "N"))
3454- iforce->dev.ff_effects_max = iforce->edata[1];
3455-
3456-/*
3457- * Display additional info.
3458- */
3459-
3460- for (i = 0; c[i]; i++)
3461- if (!get_id_packet(iforce, c + i))
3462- dump_packet("info", iforce->ecmd, iforce->edata);
3463-
3464-/*
3465- * Disable spring, enable force feedback.
3466- * FIXME: We should use iforce_set_autocenter() et al here.
3467- */
3468-
3469- send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
3470- send_packet(iforce, FF_CMD_ENABLE, "\004");
3471-
3472-/*
3473- * Find appropriate device entry
3474- */
3475-
3476- for (i = 0; iforce_device[i].idvendor; i++)
3477- if (iforce_device[i].idvendor == iforce->dev.idvendor &&
3478- iforce_device[i].idproduct == iforce->dev.idproduct)
3479- break;
3480-
3481- iforce->type = iforce_device + i;
3482-
3483- sprintf(iforce->name, iforce->type->name,
3484- iforce->dev.idproduct, iforce->dev.idvendor);
3485-
3486-/*
3487- * Set input device bitfields and ranges.
3488- */
3489-
3490- iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF);
3491-
3492- for (i = 0; iforce->type->btn[i] >= 0; i++) {
3493- signed short t = iforce->type->btn[i];
3494- set_bit(t, iforce->dev.keybit);
3495- if (t != BTN_DEAD)
3496- set_bit(FF_BTN(t), iforce->dev.ffbit);
3497- }
3498-
3499- for (i = 0; iforce->type->abs[i] >= 0; i++) {
3500-
3501- signed short t = iforce->type->abs[i];
3502- set_bit(t, iforce->dev.absbit);
3503-
3504- switch (t) {
3505-
3506- case ABS_X:
3507- case ABS_Y:
3508- case ABS_WHEEL:
3509-
3510- iforce->dev.absmax[t] = 1920;
3511- iforce->dev.absmin[t] = -1920;
3512- iforce->dev.absflat[t] = 128;
3513- iforce->dev.absfuzz[t] = 16;
3514-
3515- set_bit(FF_ABS(t), iforce->dev.ffbit);
3516- break;
3517-
3518- case ABS_THROTTLE:
3519- case ABS_GAS:
3520- case ABS_BRAKE:
3521-
3522- iforce->dev.absmax[t] = 255;
3523- iforce->dev.absmin[t] = 0;
3524- break;
3525-
3526- case ABS_HAT0X:
3527- case ABS_HAT0Y:
3528- iforce->dev.absmax[t] = 1;
3529- iforce->dev.absmin[t] = -1;
3530- break;
3531- }
3532- }
3533-
3534- for (i = 0; iforce->type->ff[i] >= 0; i++)
3535- set_bit(iforce->type->ff[i], iforce->dev.ffbit);
3536-
3537-/*
3538- * Register input device.
3539- */
3540-
3541- input_register_device(&iforce->dev);
3542-
3543- return 0;
3544-}
3545-
3546-#ifdef IFORCE_USB
3547-
3548-static void iforce_usb_irq(struct urb *urb)
3549-{
3550- struct iforce *iforce = urb->context;
3551- if (urb->status) return;
3552- iforce_process_packet(iforce,
3553- (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
3554-}
3555-
3556-static void iforce_usb_out(struct urb *urb)
3557-{
3558- struct iforce *iforce = urb->context;
3559- if (urb->status) return;
3560- if (waitqueue_active(&iforce->wait))
3561- wake_up(&iforce->wait);
3562-}
3563-
3564-static void iforce_usb_ctrl(struct urb *urb)
3565-{
3566- struct iforce *iforce = urb->context;
3567- if (urb->status) return;
3568- iforce->ecmd = 0xff00 | urb->actual_length;
3569- if (waitqueue_active(&iforce->wait))
3570- wake_up(&iforce->wait);
3571-}
3572-
3573-static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum,
3574- const struct usb_device_id *id)
3575-{
3576- struct usb_endpoint_descriptor *epirq, *epout;
3577- struct iforce *iforce;
3578-
3579- epirq = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
3580- epout = dev->config[0].interface[ifnum].altsetting[0].endpoint + 1;
3581-
3582- if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) return NULL;
3583- memset(iforce, 0, sizeof(struct iforce));
3584-
3585- iforce->bus = IFORCE_USB;
3586- iforce->usbdev = dev;
3587-
3588- iforce->dr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
3589- iforce->dr.wIndex = 0;
3590- iforce->dr.wLength = 16;
3591-
3592- FILL_INT_URB(&iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
3593- iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
3594-
3595- FILL_BULK_URB(&iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
3596- iforce + 1, 32, iforce_usb_out, iforce);
3597-
3598- FILL_CONTROL_URB(&iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
3599- (void*) &iforce->dr, iforce->edata, 16, iforce_usb_ctrl, iforce);
3600-
3601- if (iforce_init_device(iforce)) {
3602- kfree(iforce);
3603- return NULL;
3604- }
3605-
3606- printk(KERN_INFO "input%d: %s [%d effects, %ld bytes memory] on usb%d:%d.%d\n",
3607- iforce->dev.number, iforce->dev.name, iforce->dev.ff_effects_max,
3608- iforce->device_memory.end, dev->bus->busnum, dev->devnum, ifnum);
3609-
3610- return iforce;
3611-}
3612-
3613-static void iforce_usb_disconnect(struct usb_device *dev, void *ptr)
3614-{
3615- struct iforce *iforce = ptr;
3616- usb_unlink_urb(&iforce->irq);
3617- input_unregister_device(&iforce->dev);
3618- kfree(iforce);
3619-}
3620-
3621-static struct usb_device_id iforce_usb_ids [] = {
3622- { USB_DEVICE(0x046d, 0xc281) }, /* Logitech WingMan Force */
3623- { USB_DEVICE(0x046d, 0xc291) }, /* Logitech WingMan Formula Force */
3624- { USB_DEVICE(0x05ef, 0x020a) }, /* AVB Top Shot Pegasus */
3625- { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */
3626- { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */
3627- { } /* Terminating entry */
3628-};
3629-
3630-MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
3631-
3632-static struct usb_driver iforce_usb_driver = {
3633- name: "iforce",
3634- probe: iforce_usb_probe,
3635- disconnect: iforce_usb_disconnect,
3636- id_table: iforce_usb_ids,
3637-};
3638-
3639-#endif
3640-
3641-#ifdef IFORCE_232
3642-
3643-static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
3644-{
3645- struct iforce* iforce = serio->private;
3646-
3647- if (!iforce->pkt) {
3648- if (data != 0x2b) {
3649- return;
3650- }
3651- iforce->pkt = 1;
3652- return;
3653- }
3654-
3655- if (!iforce->id) {
3656- if (data > 3 && data != 0xff) {
3657- iforce->pkt = 0;
3658- return;
3659- }
3660- iforce->id = data;
3661- return;
3662- }
3663-
3664- if (!iforce->len) {
3665- if (data > IFORCE_MAX_LENGTH) {
3666- iforce->pkt = 0;
3667- iforce->id = 0;
3668- return;
3669- }
3670- iforce->len = data;
3671- return;
3672- }
3673-
3674- if (iforce->idx < iforce->len) {
3675- iforce->csum += iforce->data[iforce->idx++] = data;
3676- return;
3677- }
3678-
3679- if (iforce->idx == iforce->len) {
3680- iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
3681- iforce->pkt = 0;
3682- iforce->id = 0;
3683- iforce->len = 0;
3684- iforce->idx = 0;
3685- iforce->csum = 0;
3686- }
3687-}
3688-
3689-static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
3690-{
3691- struct iforce *iforce;
3692- if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
3693- return;
3694-
3695- if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return;
3696- memset(iforce, 0, sizeof(struct iforce));
3697-
3698- iforce->bus = IFORCE_232;
3699- iforce->serio = serio;
3700- serio->private = iforce;
3701-
3702- if (serio_open(serio, dev)) {
3703- kfree(iforce);
3704- return;
3705- }
3706-
3707- if (iforce_init_device(iforce)) {
3708- serio_close(serio);
3709- kfree(iforce);
3710- return;
3711- }
3712-
3713- printk(KERN_INFO "input%d: %s [%d effects, %ld bytes memory] on serio%d\n",
3714- iforce->dev.number, iforce->dev.name, iforce->dev.ff_effects_max,
3715- iforce->device_memory.end, serio->number);
3716-}
3717-
3718-static void iforce_serio_disconnect(struct serio *serio)
3719-{
3720- struct iforce* iforce = serio->private;
3721-
3722- input_unregister_device(&iforce->dev);
3723- serio_close(serio);
3724- kfree(iforce);
3725-}
3726-
3727-static struct serio_dev iforce_serio_dev = {
3728- interrupt: iforce_serio_irq,
3729- connect: iforce_serio_connect,
3730- disconnect: iforce_serio_disconnect,
3731-};
3732-
3733-#endif
3734-
3735-static int __init iforce_init(void)
3736-{
3737-#ifdef IFORCE_USB
3738- usb_register(&iforce_usb_driver);
3739-#endif
3740-#ifdef IFORCE_232
3741- serio_register_device(&iforce_serio_dev);
3742-#endif
3743- return 0;
3744-}
3745-
3746-static void __exit iforce_exit(void)
3747-{
3748-#ifdef IFORCE_USB
3749- usb_deregister(&iforce_usb_driver);
3750-#endif
3751-#ifdef IFORCE_232
3752- serio_unregister_device(&iforce_serio_dev);
3753-#endif
3754-}
3755-
3756-module_init(iforce_init);
3757-module_exit(iforce_exit);
3758diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/interact.c linux-modified/drivers/char/joystick/interact.c
3759--- linux-vanilla/drivers/char/joystick/interact.c Thu Sep 13 00:34:06 2001
3760+++ linux-modified/drivers/char/joystick/interact.c Mon Jan 6 16:48:20 2003
3761@@ -270,8 +270,8 @@
3762 set_bit(t, interact->dev.keybit);
3763
3764 input_register_device(&interact->dev);
3765- printk(KERN_INFO "input%d: %s on gameport%d.0\n",
3766- interact->dev.number, interact_type[interact->type].name, gameport->number);
3767+ printk(KERN_INFO "input: %s on gameport%d.0\n",
3768+ interact_type[interact->type].name, gameport->number);
3769
3770 return;
3771 fail2: gameport_close(gameport);
3772diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/magellan.c linux-modified/drivers/char/joystick/magellan.c
3773--- linux-vanilla/drivers/char/joystick/magellan.c Thu Sep 13 00:34:06 2001
3774+++ linux-modified/drivers/char/joystick/magellan.c Mon Jan 6 16:48:20 2003
3775@@ -178,7 +178,7 @@
3776
3777 input_register_device(&magellan->dev);
3778
3779- printk(KERN_INFO "input%d: %s on serio%d\n", magellan->dev.number, magellan_name, serio->number);
3780+ printk(KERN_INFO "input: %s on serio %s\n", magellan_name, serio->name);
3781 }
3782
3783 /*
3784diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/serio.c linux-modified/drivers/char/joystick/serio.c
3785--- linux-vanilla/drivers/char/joystick/serio.c Thu Sep 13 00:34:06 2001
3786+++ linux-modified/drivers/char/joystick/serio.c Mon Jan 6 16:48:20 2003
3787@@ -1,9 +1,7 @@
3788 /*
3789- * $Id$
3790+ * $Id$
3791 *
3792- * Copyright (c) 1999-2000 Vojtech Pavlik
3793- *
3794- * Sponsored by SuSE
3795+ * Copyright (c) 1999-2001 Vojtech Pavlik
3796 */
3797
3798 /*
3799@@ -27,14 +25,16 @@
3800 *
3801 * Should you need to contact me, the author, you can do so either by
3802 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
3803- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
3804+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
3805 */
3806
3807 #include <linux/stddef.h>
3808 #include <linux/module.h>
3809 #include <linux/serio.h>
3810+#include <linux/errno.h>
3811
3812 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
3813+MODULE_DESCRIPTION("Serio abstraction core");
3814 MODULE_LICENSE("GPL");
3815
3816 EXPORT_SYMBOL(serio_register_port);
3817@@ -47,7 +47,6 @@
3818
3819 static struct serio *serio_list;
3820 static struct serio_dev *serio_dev;
3821-static int serio_number;
3822
3823 static void serio_find_dev(struct serio *serio)
3824 {
3825@@ -69,7 +68,6 @@
3826
3827 void serio_register_port(struct serio *serio)
3828 {
3829- serio->number = serio_number++;
3830 serio->next = serio_list;
3831 serio_list = serio;
3832 serio_find_dev(serio);
3833@@ -84,8 +82,6 @@
3834
3835 if (serio->dev && serio->dev->disconnect)
3836 serio->dev->disconnect(serio);
3837-
3838- serio_number--;
3839 }
3840
3841 void serio_register_device(struct serio_dev *dev)
3842diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/serport.c linux-modified/drivers/char/joystick/serport.c
3843--- linux-vanilla/drivers/char/joystick/serport.c Thu Sep 13 00:34:06 2001
3844+++ linux-modified/drivers/char/joystick/serport.c Mon Jan 6 16:48:20 2003
3845@@ -1,9 +1,7 @@
3846 /*
3847- * $Id$
3848+ * $Id$
3849 *
3850 * Copyright (c) 1999-2001 Vojtech Pavlik
3851- *
3852- * Sponsored by SuSE
3853 */
3854
3855 /*
3856@@ -28,7 +26,7 @@
3857 *
3858 * Should you need to contact me, the author, you can do so either by
3859 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
3860- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
3861+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
3862 */
3863
3864 #include <asm/uaccess.h>
3865@@ -39,12 +37,19 @@
3866 #include <linux/serio.h>
3867 #include <linux/tty.h>
3868
3869+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
3870+MODULE_DESCRIPTION("Input device TTY line discipline");
3871+MODULE_LICENSE("GPL");
3872+
3873 struct serport {
3874 struct tty_struct *tty;
3875 wait_queue_head_t wait;
3876 struct serio serio;
3877+ char phys[32];
3878 };
3879
3880+char serport_name[] = "Serial port";
3881+
3882 /*
3883 * Callback functions from the serio code.
3884 */
3885@@ -75,6 +80,8 @@
3886 static int serport_ldisc_open(struct tty_struct *tty)
3887 {
3888 struct serport *serport;
3889+ char ttyname[64];
3890+ int i;
3891
3892 MOD_INC_USE_COUNT;
3893
3894@@ -85,9 +92,19 @@
3895
3896 memset(serport, 0, sizeof(struct serport));
3897
3898+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
3899 serport->tty = tty;
3900 tty->disc_data = serport;
3901
3902+ strcpy(ttyname, tty->driver.name);
3903+ for (i = 0; ttyname[i] != 0 && ttyname[i] != '/'; i++);
3904+ ttyname[i] = 0;
3905+
3906+ sprintf(serport->phys, "%s%d/serio0", ttyname, MINOR(tty->device) - tty->driver.minor_start);
3907+
3908+ serport->serio.name = serport_name;
3909+ serport->serio.phys = serport->phys;
3910+
3911 serport->serio.type = SERIO_RS232;
3912 serport->serio.write = serport_serio_write;
3913 serport->serio.open = serport_serio_open;
3914@@ -156,14 +173,14 @@
3915
3916 serio_register_port(&serport->serio);
3917
3918- printk(KERN_INFO "serio%d: Serial port %s\n", serport->serio.number, name);
3919+ printk(KERN_INFO "serio: Serial port %s\n", name);
3920
3921 add_wait_queue(&serport->wait, &wait);
3922- current->state = TASK_INTERRUPTIBLE;
3923+ set_current_state(TASK_INTERRUPTIBLE);
3924
3925 while(serport->serio.type && !signal_pending(current)) schedule();
3926
3927- current->state = TASK_RUNNING;
3928+ set_current_state(TASK_RUNNING);
3929 remove_wait_queue(&serport->wait, &wait);
3930
3931 serio_unregister_port(&serport->serio);
3932@@ -187,6 +204,14 @@
3933 return -EINVAL;
3934 }
3935
3936+static void serport_ldisc_write_wakeup(struct tty_struct * tty)
3937+{
3938+ struct serport *sp = (struct serport *) tty->disc_data;
3939+
3940+ serio_dev_write_wakeup(&sp->serio);
3941+
3942+}
3943+
3944 /*
3945 * The line discipline structure.
3946 */
3947@@ -199,6 +224,7 @@
3948 ioctl: serport_ldisc_ioctl,
3949 receive_buf: serport_ldisc_receive,
3950 receive_room: serport_ldisc_room,
3951+ write_wakeup: serport_ldisc_write_wakeup
3952 };
3953
3954 /*
3955@@ -222,5 +248,3 @@
3956
3957 module_init(serport_init);
3958 module_exit(serport_exit);
3959-
3960-MODULE_LICENSE("GPL");
3961diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/sidewinder.c linux-modified/drivers/char/joystick/sidewinder.c
3962--- linux-vanilla/drivers/char/joystick/sidewinder.c Thu Sep 13 00:34:06 2001
3963+++ linux-modified/drivers/char/joystick/sidewinder.c Mon Jan 6 16:48:20 2003
3964@@ -719,8 +719,8 @@
3965 set_bit(code, sw->dev[i].keybit);
3966
3967 input_register_device(sw->dev + i);
3968- printk(KERN_INFO "input%d: %s%s on gameport%d.%d [%d-bit id %d data %d]\n",
3969- sw->dev[i].number, sw->name, comment, gameport->number, i, m, l, k);
3970+ printk(KERN_INFO "input: %s%s on gameport%d.%d [%d-bit id %d data %d]\n",
3971+ sw->name, comment, gameport->number, i, m, l, k);
3972 }
3973
3974 return;
3975diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/spaceball.c linux-modified/drivers/char/joystick/spaceball.c
3976--- linux-vanilla/drivers/char/joystick/spaceball.c Thu Sep 13 00:34:06 2001
3977+++ linux-modified/drivers/char/joystick/spaceball.c Mon Jan 6 16:48:20 2003
3978@@ -81,8 +81,8 @@
3979 case '@': /* Reset packet */
3980 spaceball->data[spaceball->idx - 1] = 0;
3981 for (i = 1; i < spaceball->idx && spaceball->data[i] == ' '; i++);
3982- printk(KERN_INFO "input%d: %s [%s] on serio%d\n",
3983- spaceball->dev.number, spaceball_name, spaceball->data + i, spaceball->serio->number);
3984+ printk(KERN_INFO "input: %s [%s] on serio %s\n",
3985+ spaceball_name, spaceball->data + i, spaceball->serio->name);
3986 break;
3987
3988 case 'D': /* Ball data */
3989diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/spaceorb.c linux-modified/drivers/char/joystick/spaceorb.c
3990--- linux-vanilla/drivers/char/joystick/spaceorb.c Thu Sep 13 00:34:06 2001
3991+++ linux-modified/drivers/char/joystick/spaceorb.c Mon Jan 6 16:48:20 2003
3992@@ -88,8 +88,8 @@
3993 case 'R': /* Reset packet */
3994 spaceorb->data[spaceorb->idx - 1] = 0;
3995 for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
3996- printk(KERN_INFO "input%d: %s [%s] on serio%d\n",
3997- spaceorb->dev.number, spaceorb_name, spaceorb->data + i, spaceorb->serio->number);
3998+ printk(KERN_INFO "input: %s [%s] on serio %s\n",
3999+ spaceorb_name, spaceorb->data + i, spaceorb->serio->name);
4000 break;
4001
4002 case 'D': /* Ball + button data */
4003diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/stinger.c linux-modified/drivers/char/joystick/stinger.c
4004--- linux-vanilla/drivers/char/joystick/stinger.c Thu Sep 13 00:34:06 2001
4005+++ linux-modified/drivers/char/joystick/stinger.c Mon Jan 6 16:48:20 2003
4006@@ -168,7 +168,7 @@
4007
4008 input_register_device(&stinger->dev);
4009
4010- printk(KERN_INFO "input%d: %s on serio%d\n", stinger->dev.number, stinger_name, serio->number);
4011+ printk(KERN_INFO "input: %s on serio %s\n", stinger_name, serio->name);
4012 }
4013
4014 /*
4015diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/tmdc.c linux-modified/drivers/char/joystick/tmdc.c
4016--- linux-vanilla/drivers/char/joystick/tmdc.c Thu Sep 13 00:34:06 2001
4017+++ linux-modified/drivers/char/joystick/tmdc.c Mon Jan 6 16:48:20 2003
4018@@ -336,8 +336,8 @@
4019 }
4020
4021 input_register_device(tmdc->dev + j);
4022- printk(KERN_INFO "input%d: %s on gameport%d.%d\n",
4023- tmdc->dev[j].number, tmdc->name[j], gameport->number, j);
4024+ printk(KERN_INFO "input: %s on gameport%d.%d\n",
4025+ tmdc->name[j], gameport->number, j);
4026 }
4027
4028 return;
4029diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/turbografx.c linux-modified/drivers/char/joystick/turbografx.c
4030--- linux-vanilla/drivers/char/joystick/turbografx.c Thu Sep 13 00:34:06 2001
4031+++ linux-modified/drivers/char/joystick/turbografx.c Mon Jan 6 16:48:20 2003
4032@@ -190,8 +190,8 @@
4033 tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
4034
4035 input_register_device(tgfx->dev + i);
4036- printk(KERN_INFO "input%d: %d-button Multisystem joystick on %s\n",
4037- tgfx->dev[i].number, config[i+1], tgfx->pd->port->name);
4038+ printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n",
4039+ config[i+1], tgfx->pd->port->name);
4040 }
4041
4042 if (!tgfx->sticks) {
4043diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/char/joystick/warrior.c linux-modified/drivers/char/joystick/warrior.c
4044--- linux-vanilla/drivers/char/joystick/warrior.c Thu Sep 13 00:34:06 2001
4045+++ linux-modified/drivers/char/joystick/warrior.c Mon Jan 6 16:48:20 2003
4046@@ -180,7 +180,7 @@
4047
4048 input_register_device(&warrior->dev);
4049
4050- printk(KERN_INFO "input%d: Logitech WingMan Warrior on serio%d\n", warrior->dev.number, serio->number);
4051+ printk(KERN_INFO "input: Logitech WingMan Warrior on serio %s\n", serio->name);
4052 }
4053
4054 /*
4055diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/input/evdev.c linux-modified/drivers/input/evdev.c
4056--- linux-vanilla/drivers/input/evdev.c Mon Feb 25 21:37:58 2002
4057+++ linux-modified/drivers/input/evdev.c Mon Jan 6 16:48:20 2003
4058@@ -1,11 +1,9 @@
4059 /*
4060- * $Id$
4061+ * $Id$
4062 *
4063 * Copyright (c) 1999-2001 Vojtech Pavlik
4064 *
4065 * Event char devices, giving access to raw input device events.
4066- *
4067- * Sponsored by SuSE
4068 */
4069
4070 /*
4071@@ -24,8 +22,8 @@
4072 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4073 *
4074 * Should you need to contact me, the author, you can do so either by
4075- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
4076- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
4077+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
4078+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
4079 */
4080
4081 #define EVDEV_MINOR_BASE 64
4082@@ -43,6 +41,7 @@
4083 int exist;
4084 int open;
4085 int minor;
4086+ char name[16];
4087 struct input_handle handle;
4088 wait_queue_head_t wait;
4089 devfs_handle_t devfs;
4090@@ -89,12 +88,20 @@
4091 return retval < 0 ? retval : 0;
4092 }
4093
4094+static int evdev_flush(struct file * file)
4095+{
4096+ struct evdev_list *list = (struct evdev_list*)file->private_data;
4097+
4098+ if (!list->evdev->exist) return -ENODEV;
4099+
4100+ return input_flush_device(&list->evdev->handle, file);
4101+}
4102+
4103 static int evdev_release(struct inode * inode, struct file * file)
4104 {
4105 struct evdev_list *list = file->private_data;
4106 struct evdev_list **listptr;
4107
4108- lock_kernel();
4109 listptr = &list->evdev->list;
4110 evdev_fasync(-1, file, 0);
4111
4112@@ -113,8 +120,7 @@
4113 }
4114
4115 kfree(list);
4116- unlock_kernel();
4117-
4118+
4119 return 0;
4120 }
4121
4122@@ -122,10 +128,16 @@
4123 {
4124 struct evdev_list *list;
4125 int i = MINOR(inode->i_rdev) - EVDEV_MINOR_BASE;
4126+ int accept_err;
4127
4128 if (i >= EVDEV_MINORS || !evdev_table[i])
4129 return -ENODEV;
4130
4131+ /* Ask the driver if he wishes to accept the open() */
4132+ if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) {
4133+ return accept_err;
4134+ }
4135+
4136 if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
4137 return -ENOMEM;
4138 memset(list, 0, sizeof(struct evdev_list));
4139@@ -149,6 +161,8 @@
4140 struct input_event event;
4141 int retval = 0;
4142
4143+ if (!list->evdev->exist) return -ENODEV;
4144+
4145 while (retval < count) {
4146
4147 if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
4148@@ -169,7 +183,7 @@
4149 if (list->head == list->tail) {
4150
4151 add_wait_queue(&list->evdev->wait, &wait);
4152- current->state = TASK_INTERRUPTIBLE;
4153+ set_current_state(TASK_INTERRUPTIBLE);
4154
4155 while (list->head == list->tail) {
4156
4157@@ -189,7 +203,7 @@
4158 schedule();
4159 }
4160
4161- current->state = TASK_RUNNING;
4162+ set_current_state(TASK_RUNNING);
4163 remove_wait_queue(&list->evdev->wait, &wait);
4164 }
4165
4166@@ -221,7 +235,9 @@
4167 struct evdev_list *list = file->private_data;
4168 struct evdev *evdev = list->evdev;
4169 struct input_dev *dev = evdev->handle.dev;
4170- int retval;
4171+ int retval, t, u;
4172+
4173+ if (!evdev->exist) return -ENODEV;
4174
4175 switch (cmd) {
4176
4177@@ -234,6 +250,40 @@
4178 if ((retval = put_user(dev->idproduct, ((short *) arg) + 2))) return retval;
4179 if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval;
4180 return 0;
4181+
4182+ case EVIOCGREP:
4183+ if ((retval = put_user(dev->rep[0], ((int *) arg) + 0))) return retval;
4184+ if ((retval = put_user(dev->rep[1], ((int *) arg) + 1))) return retval;
4185+ return 0;
4186+
4187+ case EVIOCSREP:
4188+ if ((retval = get_user(dev->rep[0], ((int *) arg) + 0))) return retval;
4189+ if ((retval = get_user(dev->rep[1], ((int *) arg) + 1))) return retval;
4190+ return 0;
4191+
4192+ case EVIOCGKEYCODE:
4193+ if ((retval = get_user(t, ((int *) arg) + 0))) return retval;
4194+ if (t < 0 || t > dev->keycodemax) return -EINVAL;
4195+ switch (dev->keycodesize) {
4196+ case 1: u = *(u8*)(dev->keycode + t); break;
4197+ case 2: u = *(u16*)(dev->keycode + t * 2); break;
4198+ case 4: u = *(u32*)(dev->keycode + t * 4); break;
4199+ default: return -EINVAL;
4200+ }
4201+ if ((retval = put_user(u, ((int *) arg) + 1))) return retval;
4202+ return 0;
4203+
4204+ case EVIOCSKEYCODE:
4205+ if ((retval = get_user(t, ((int *) arg) + 0))) return retval;
4206+ if (t < 0 || t > dev->keycodemax) return -EINVAL;
4207+ if ((retval = get_user(u, ((int *) arg) + 1))) return retval;
4208+ switch (dev->keycodesize) {
4209+ case 1: *(u8*)(dev->keycode + t) = u; break;
4210+ case 2: *(u16*)(dev->keycode + t * 2) = u; break;
4211+ case 4: *(u32*)(dev->keycode + t * 4) = u; break;
4212+ default: return -EINVAL;
4213+ }
4214+ return 0;
4215
4216 case EVIOCSFF:
4217 if (dev->upload_effect) {
4218@@ -282,22 +332,55 @@
4219 default: return -EINVAL;
4220 }
4221 len = NBITS(len) * sizeof(long);
4222- if (len > _IOC_SIZE(cmd)) {
4223- printk(KERN_WARNING "evdev.c: Truncating bitfield length from %d to %d\n",
4224- len, _IOC_SIZE(cmd));
4225- len = _IOC_SIZE(cmd);
4226- }
4227+ if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4228 return copy_to_user((char *) arg, bits, len) ? -EFAULT : len;
4229 }
4230
4231+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
4232+ int len;
4233+ len = NBITS(KEY_MAX) * sizeof(long);
4234+ if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4235+ return copy_to_user((char *) arg, dev->key, len) ? -EFAULT : len;
4236+ }
4237+
4238+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
4239+ int len;
4240+ len = NBITS(LED_MAX) * sizeof(long);
4241+ if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4242+ return copy_to_user((char *) arg, dev->led, len) ? -EFAULT : len;
4243+ }
4244+
4245+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
4246+ int len;
4247+ len = NBITS(SND_MAX) * sizeof(long);
4248+ if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4249+ return copy_to_user((char *) arg, dev->snd, len) ? -EFAULT : len;
4250+ }
4251+
4252 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
4253 int len;
4254- if (!dev->name) return 0;
4255+ if (!dev->name) return -ENOENT;
4256 len = strlen(dev->name) + 1;
4257 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4258 return copy_to_user((char *) arg, dev->name, len) ? -EFAULT : len;
4259 }
4260
4261+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
4262+ int len;
4263+ if (!dev->phys) return -ENOENT;
4264+ len = strlen(dev->phys) + 1;
4265+ if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4266+ return copy_to_user((char *) arg, dev->phys, len) ? -EFAULT : len;
4267+ }
4268+
4269+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
4270+ int len;
4271+ if (!dev->uniq) return -ENOENT;
4272+ len = strlen(dev->uniq) + 1;
4273+ if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4274+ return copy_to_user((char *) arg, dev->uniq, len) ? -EFAULT : len;
4275+ }
4276+
4277 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
4278
4279 int t = _IOC_NR(cmd) & ABS_MAX;
4280@@ -323,9 +406,10 @@
4281 release: evdev_release,
4282 ioctl: evdev_ioctl,
4283 fasync: evdev_fasync,
4284+ flush: evdev_flush
4285 };
4286
4287-static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev)
4288+static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
4289 {
4290 struct evdev *evdev;
4291 int minor;
4292@@ -344,16 +428,17 @@
4293
4294 evdev->minor = minor;
4295 evdev_table[minor] = evdev;
4296+
4297+ sprintf(evdev->name, "event%d", minor);
4298
4299 evdev->handle.dev = dev;
4300+ evdev->handle.name = evdev->name;
4301 evdev->handle.handler = handler;
4302 evdev->handle.private = evdev;
4303
4304- evdev->exist = 1;
4305-
4306 evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
4307
4308-// printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number);
4309+ evdev->exist = 1;
4310
4311 return &evdev->handle;
4312 }
4313@@ -374,12 +459,21 @@
4314 }
4315 }
4316
4317+static struct input_device_id evdev_ids[] = {
4318+ { driver_info: 1 }, /* Matches all devices */
4319+ { }, /* Terminating zero entry */
4320+};
4321+
4322+MODULE_DEVICE_TABLE(input, evdev_ids);
4323+
4324 static struct input_handler evdev_handler = {
4325 event: evdev_event,
4326 connect: evdev_connect,
4327 disconnect: evdev_disconnect,
4328 fops: &evdev_fops,
4329 minor: EVDEV_MINOR_BASE,
4330+ name: "evdev",
4331+ id_table: evdev_ids,
4332 };
4333
4334 static int __init evdev_init(void)
4335@@ -396,7 +490,6 @@
4336 module_init(evdev_init);
4337 module_exit(evdev_exit);
4338
4339-MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
4340-MODULE_DESCRIPTION("Event character device driver");
4341+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
4342+MODULE_DESCRIPTION("Input driver event char devices");
4343 MODULE_LICENSE("GPL");
4344-
4345diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/input/input.c linux-modified/drivers/input/input.c
4346--- linux-vanilla/drivers/input/input.c Mon Jan 6 15:58:02 2003
4347+++ linux-modified/drivers/input/input.c Mon Jan 6 16:48:20 2003
4348@@ -1,11 +1,9 @@
4349 /*
4350- * $Id$
4351+ * $Id$
4352 *
4353 * Copyright (c) 1999-2001 Vojtech Pavlik
4354 *
4355- * The input layer module itself
4356- *
4357- * Sponsored by SuSE
4358+ * The input core
4359 */
4360
4361 /*
4362@@ -24,8 +22,8 @@
4363 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4364 *
4365 * Should you need to contact me, the author, you can do so either by
4366- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
4367- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
4368+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
4369+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
4370 */
4371
4372 #include <linux/init.h>
4373@@ -34,12 +32,16 @@
4374 #include <linux/input.h>
4375 #include <linux/module.h>
4376 #include <linux/random.h>
4377+#include <linux/pm.h>
4378+#include <linux/proc_fs.h>
4379+#include <linux/kmod.h>
4380+#include <linux/interrupt.h>
4381+#include <linux/poll.h>
4382
4383-MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
4384-MODULE_DESCRIPTION("Input layer module");
4385+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
4386+MODULE_DESCRIPTION("Input core");
4387 MODULE_LICENSE("GPL");
4388
4389-
4390 EXPORT_SYMBOL(input_register_device);
4391 EXPORT_SYMBOL(input_unregister_device);
4392 EXPORT_SYMBOL(input_register_handler);
4393@@ -48,6 +50,8 @@
4394 EXPORT_SYMBOL(input_unregister_minor);
4395 EXPORT_SYMBOL(input_open_device);
4396 EXPORT_SYMBOL(input_close_device);
4397+EXPORT_SYMBOL(input_accept_process);
4398+EXPORT_SYMBOL(input_flush_device);
4399 EXPORT_SYMBOL(input_event);
4400
4401 #define INPUT_MAJOR 13
4402@@ -57,20 +61,32 @@
4403 static struct input_handler *input_handler;
4404 static struct input_handler *input_table[8];
4405 static devfs_handle_t input_devfs_handle;
4406-static int input_number;
4407-static long input_devices[NBITS(INPUT_DEVICES)];
4408+
4409+#ifdef CONFIG_PROC_FS
4410+static struct proc_dir_entry *proc_bus_input_dir;
4411+DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait);
4412+static int input_devices_state;
4413+#endif
4414
4415 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
4416 {
4417 struct input_handle *handle = dev->handle;
4418
4419 /*
4420+ * Wake up the device if it is sleeping.
4421+ */
4422+ if (dev->pm_dev)
4423+ pm_access(dev->pm_dev);
4424+
4425+/*
4426 * Filter non-events, and bad input values out.
4427 */
4428
4429 if (type > EV_MAX || !test_bit(type, dev->evbit))
4430 return;
4431
4432+ add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
4433+
4434 switch (type) {
4435
4436 case EV_KEY:
4437@@ -187,16 +203,36 @@
4438 mod_timer(&dev->timer, jiffies + dev->rep[REP_PERIOD]);
4439 }
4440
4441+int input_accept_process(struct input_handle *handle, struct file *file)
4442+{
4443+ if (handle->dev->accept)
4444+ return handle->dev->accept(handle->dev, file);
4445+
4446+ return 0;
4447+}
4448+
4449 int input_open_device(struct input_handle *handle)
4450 {
4451+ if (handle->dev->pm_dev)
4452+ pm_access(handle->dev->pm_dev);
4453 handle->open++;
4454 if (handle->dev->open)
4455 return handle->dev->open(handle->dev);
4456 return 0;
4457 }
4458
4459+int input_flush_device(struct input_handle* handle, struct file* file)
4460+{
4461+ if (handle->dev->flush)
4462+ return handle->dev->flush(handle->dev, file);
4463+
4464+ return 0;
4465+}
4466+
4467 void input_close_device(struct input_handle *handle)
4468 {
4469+ if (handle->dev->pm_dev)
4470+ pm_dev_idle(handle->dev->pm_dev);
4471 if (handle->dev->close)
4472 handle->dev->close(handle->dev);
4473 handle->open--;
4474@@ -210,25 +246,197 @@
4475 handle->handler->handle = handle;
4476 }
4477
4478+/**
4479+ * input_find_and_remove - Find and remove node
4480+ *
4481+ * @type: data type
4482+ * @initval: initial value
4483+ * @targ: node to find
4484+ * @next: next node in the list
4485+ *
4486+ * Searches the linked list for the target node @targ. If the node
4487+ * is found, it is removed from the list.
4488+ *
4489+ * If the node is not found, the end of the list will be hit,
4490+ * indicating that it wasn't in the list to begin with.
4491+ *
4492+ * Returns nothing.
4493+ */
4494+#define input_find_and_remove(type, initval, targ, next) \
4495+ do { \
4496+ type **ptr; \
4497+ for (ptr = &initval; *ptr; ptr = &((*ptr)->next)) \
4498+ if (*ptr == targ) break; \
4499+ if (*ptr) *ptr = (*ptr)->next; \
4500+ } while (0)
4501+
4502 static void input_unlink_handle(struct input_handle *handle)
4503 {
4504- struct input_handle **handleptr;
4505+ input_find_and_remove(struct input_handle, handle->dev->handle, handle, dnext);
4506+ input_find_and_remove(struct input_handle, handle->handler->handle, handle, hnext);
4507+}
4508+
4509+#define MATCH_BIT(bit, max) \
4510+ for (i = 0; i < NBITS(max); i++) \
4511+ if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
4512+ break; \
4513+ if (i != NBITS(max)) \
4514+ continue;
4515+
4516+static struct input_device_id *input_match_device(struct input_device_id *id, struct input_dev *dev)
4517+{
4518+ int i;
4519+
4520+ for (; id->flags || id->driver_info; id++) {
4521+
4522+ if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
4523+ if (id->idbus != dev->idbus)
4524+ continue;
4525
4526- handleptr = &handle->dev->handle;
4527- while (*handleptr && (*handleptr != handle))
4528- handleptr = &((*handleptr)->dnext);
4529- *handleptr = (*handleptr)->dnext;
4530-
4531- handleptr = &handle->handler->handle;
4532- while (*handleptr && (*handleptr != handle))
4533- handleptr = &((*handleptr)->hnext);
4534- *handleptr = (*handleptr)->hnext;
4535+ if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
4536+ if (id->idvendor != dev->idvendor)
4537+ continue;
4538+
4539+ if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
4540+ if (id->idproduct != dev->idproduct)
4541+ continue;
4542+
4543+ if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
4544+ if (id->idversion != dev->idversion)
4545+ continue;
4546+
4547+ MATCH_BIT(evbit, EV_MAX);
4548+ MATCH_BIT(keybit, KEY_MAX);
4549+ MATCH_BIT(relbit, REL_MAX);
4550+ MATCH_BIT(absbit, ABS_MAX);
4551+ MATCH_BIT(mscbit, MSC_MAX);
4552+ MATCH_BIT(ledbit, LED_MAX);
4553+ MATCH_BIT(sndbit, SND_MAX);
4554+ MATCH_BIT(ffbit, FF_MAX);
4555+
4556+ return id;
4557+ }
4558+
4559+ return NULL;
4560 }
4561
4562+/*
4563+ * Input hotplugging interface - loading event handlers based on
4564+ * device bitfields.
4565+ */
4566+
4567+#ifdef CONFIG_HOTPLUG
4568+
4569+/*
4570+ * Input hotplugging invokes what /proc/sys/kernel/hotplug says
4571+ * (normally /sbin/hotplug) when input devices get added or removed.
4572+ *
4573+ * This invokes a user mode policy agent, typically helping to load driver
4574+ * or other modules, configure the device, and more. Drivers can provide
4575+ * a MODULE_DEVICE_TABLE to help with module loading subtasks.
4576+ *
4577+ */
4578+
4579+#define SPRINTF_BIT_A(bit, name, max) \
4580+ do { \
4581+ envp[i++] = scratch; \
4582+ scratch += sprintf(scratch, name); \
4583+ for (j = NBITS(max) - 1; j >= 0; j--) \
4584+ if (dev->bit[j]) break; \
4585+ for (; j >= 0; j--) \
4586+ scratch += sprintf(scratch, "%lx ", dev->bit[j]); \
4587+ scratch++; \
4588+ } while (0)
4589+
4590+#define SPRINTF_BIT_A2(bit, name, max, ev) \
4591+ do { \
4592+ if (test_bit(ev, dev->evbit)) \
4593+ SPRINTF_BIT_A(bit, name, max); \
4594+ } while (0)
4595+
4596+static void input_call_hotplug(char *verb, struct input_dev *dev)
4597+{
4598+ char *argv[3], **envp, *buf, *scratch;
4599+ int i = 0, j, value;
4600+
4601+ if (!hotplug_path[0]) {
4602+ printk(KERN_ERR "input.c: calling hotplug a hotplug agent defined\n");
4603+ return;
4604+ }
4605+ if (in_interrupt()) {
4606+ printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
4607+ return;
4608+ }
4609+ if (!current->fs->root) {
4610+ printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
4611+ return;
4612+ }
4613+ if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
4614+ printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
4615+ return;
4616+ }
4617+ if (!(buf = kmalloc(1024, GFP_KERNEL))) {
4618+ kfree (envp);
4619+ printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
4620+ return;
4621+ }
4622+
4623+ argv[0] = hotplug_path;
4624+ argv[1] = "input";
4625+ argv[2] = 0;
4626+
4627+ envp[i++] = "HOME=/";
4628+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
4629+
4630+ scratch = buf;
4631+
4632+ envp[i++] = scratch;
4633+ scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
4634+
4635+ envp[i++] = scratch;
4636+ scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
4637+ dev->idbus, dev->idvendor, dev->idproduct, dev->idversion) + 1;
4638+
4639+ if (dev->name) {
4640+ envp[i++] = scratch;
4641+ scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
4642+ }
4643+
4644+ if (dev->phys) {
4645+ envp[i++] = scratch;
4646+ scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
4647+ }
4648+
4649+ SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
4650+ SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
4651+ SPRINTF_BIT_A2(relbit, "REL=", REL_MAX, EV_REL);
4652+ SPRINTF_BIT_A2(absbit, "ABS=", ABS_MAX, EV_ABS);
4653+ SPRINTF_BIT_A2(mscbit, "MSC=", MSC_MAX, EV_MSC);
4654+ SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
4655+ SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
4656+ SPRINTF_BIT_A2(ffbit, "FF=", FF_MAX, EV_FF);
4657+
4658+ envp[i++] = 0;
4659+
4660+ printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n",
4661+ argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]);
4662+
4663+ value = call_usermodehelper(argv [0], argv, envp);
4664+
4665+ kfree(buf);
4666+ kfree(envp);
4667+
4668+ if (value != 0)
4669+ printk(KERN_WARNING "input.c: hotplug returned %d\n", value);
4670+}
4671+
4672+#endif
4673+
4674 void input_register_device(struct input_dev *dev)
4675 {
4676 struct input_handler *handler = input_handler;
4677 struct input_handle *handle;
4678+ struct input_device_id *id;
4679
4680 /*
4681 * Initialize repeat timer to default values.
4682@@ -244,35 +452,70 @@
4683 * Add the device.
4684 */
4685
4686- if (input_number >= INPUT_DEVICES) {
4687- printk(KERN_WARNING "input: ran out of input device numbers!\n");
4688- dev->number = input_number;
4689- } else {
4690- dev->number = find_first_zero_bit(input_devices, INPUT_DEVICES);
4691- set_bit(dev->number, input_devices);
4692- }
4693-
4694 dev->next = input_dev;
4695 input_dev = dev;
4696- input_number++;
4697
4698 /*
4699 * Notify handlers.
4700 */
4701
4702 while (handler) {
4703- if ((handle = handler->connect(handler, dev)))
4704- input_link_handle(handle);
4705+ if ((id = input_match_device(handler->id_table, dev)))
4706+ if ((handle = handler->connect(handler, dev, id)))
4707+ input_link_handle(handle);
4708 handler = handler->next;
4709 }
4710+
4711+/*
4712+ * Notify the hotplug agent.
4713+ */
4714+
4715+#ifdef CONFIG_HOTPLUG
4716+ input_call_hotplug("add", dev);
4717+#endif
4718+
4719+/*
4720+ * Notify /proc.
4721+ */
4722+
4723+#ifdef CONFIG_PROC_FS
4724+ input_devices_state++;
4725+ wake_up(&input_devices_poll_wait);
4726+#endif
4727+}
4728+
4729+#define DUMP_ARRAY(n, array) \
4730+printk(KERN_DEBUG " ");\
4731+for (i=0; i<NBITS(n); ++i)\
4732+ printk("%0X ", array[i]);\
4733+printk("\n");
4734+
4735+void dump_id_table(struct input_device_id* id)
4736+{
4737+ int i;
4738+
4739+ printk(KERN_DEBUG "flags = %0X\n", id->flags);
4740+ if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT) {
4741+ DUMP_ARRAY(NBITS(EV_MAX), id->evbit);
4742+ }
4743+ if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) {
4744+ DUMP_ARRAY(NBITS(KEY_MAX), id->keybit);
4745+ }
4746 }
4747
4748 void input_unregister_device(struct input_dev *dev)
4749 {
4750 struct input_handle *handle = dev->handle;
4751- struct input_dev **devptr = &input_dev;
4752 struct input_handle *dnext;
4753
4754+ if (!dev) return;
4755+
4756+/*
4757+ * Turn off power management for the device.
4758+ */
4759+ if (dev->pm_dev)
4760+ pm_unregister(dev->pm_dev);
4761+
4762 /*
4763 * Kill any pending repeat timers.
4764 */
4765@@ -291,23 +534,35 @@
4766 }
4767
4768 /*
4769- * Remove the device.
4770+ * Notify the hotplug agent.
4771 */
4772
4773- while (*devptr && (*devptr != dev))
4774- devptr = &((*devptr)->next);
4775- *devptr = (*devptr)->next;
4776+#ifdef CONFIG_HOTPLUG
4777+ input_call_hotplug("remove", dev);
4778+#endif
4779+
4780+/*
4781+ * Remove the device.
4782+ */
4783+ input_find_and_remove(struct input_dev, input_dev, dev, next);
4784
4785- input_number--;
4786+/*
4787+ * Notify /proc.
4788+ */
4789
4790- if (dev->number < INPUT_DEVICES)
4791- clear_bit(dev->number, input_devices);
4792+#ifdef CONFIG_PROC_FS
4793+ input_devices_state++;
4794+ wake_up(&input_devices_poll_wait);
4795+#endif
4796 }
4797
4798 void input_register_handler(struct input_handler *handler)
4799 {
4800 struct input_dev *dev = input_dev;
4801 struct input_handle *handle;
4802+ struct input_device_id *id;
4803+
4804+ if (!handler) return;
4805
4806 /*
4807 * Add minors if needed.
4808@@ -326,17 +581,27 @@
4809 /*
4810 * Notify it about all existing devices.
4811 */
4812+// dump_id_table(handler->id_table);
4813
4814 while (dev) {
4815- if ((handle = handler->connect(handler, dev)))
4816- input_link_handle(handle);
4817+ if ((id = input_match_device(handler->id_table, dev)))
4818+ if ((handle = handler->connect(handler, dev, id)))
4819+ input_link_handle(handle);
4820 dev = dev->next;
4821 }
4822+
4823+/*
4824+ * Notify /proc.
4825+ */
4826+
4827+#ifdef CONFIG_PROC_FS
4828+ input_devices_state++;
4829+ wake_up(&input_devices_poll_wait);
4830+#endif
4831 }
4832
4833 void input_unregister_handler(struct input_handler *handler)
4834 {
4835- struct input_handler **handlerptr = &input_handler;
4836 struct input_handle *handle = handler->handle;
4837 struct input_handle *hnext;
4838
4839@@ -354,18 +619,23 @@
4840 /*
4841 * Remove it.
4842 */
4843-
4844- while (*handlerptr && (*handlerptr != handler))
4845- handlerptr = &((*handlerptr)->next);
4846-
4847- *handlerptr = (*handlerptr)->next;
4848+ input_find_and_remove(struct input_handler, input_handler, handler,
4849+ next);
4850
4851 /*
4852 * Remove minors.
4853 */
4854-
4855 if (handler->fops != NULL)
4856 input_table[handler->minor >> 5] = NULL;
4857+
4858+/*
4859+ * Notify /proc.
4860+ */
4861+
4862+#ifdef CONFIG_PROC_FS
4863+ input_devices_state++;
4864+ wake_up(&input_devices_poll_wait);
4865+#endif
4866 }
4867
4868 static int input_open_file(struct inode *inode, struct file *file)
4869@@ -389,9 +659,7 @@
4870 old_fops = file->f_op;
4871 file->f_op = new_fops;
4872
4873- lock_kernel();
4874 err = new_fops->open(inode, file);
4875- unlock_kernel();
4876
4877 if (err) {
4878 fops_put(file->f_op);
4879@@ -419,18 +687,164 @@
4880 devfs_unregister(handle);
4881 }
4882
4883+/*
4884+ * ProcFS interface for the input drivers.
4885+ */
4886+
4887+#ifdef CONFIG_PROC_FS
4888+
4889+#define SPRINTF_BIT_B(bit, name, max) \
4890+ do { \
4891+ len += sprintf(buf + len, "B: %s", name); \
4892+ for (i = NBITS(max) - 1; i >= 0; i--) \
4893+ if (dev->bit[i]) break; \
4894+ for (; i >= 0; i--) \
4895+ len += sprintf(buf + len, "%lx ", dev->bit[i]); \
4896+ len += sprintf(buf + len, "\n"); \
4897+ } while (0)
4898+
4899+#define SPRINTF_BIT_B2(bit, name, max, ev) \
4900+ do { \
4901+ if (test_bit(ev, dev->evbit)) \
4902+ SPRINTF_BIT_B(bit, name, max); \
4903+ } while (0)
4904+
4905+
4906+static unsigned int input_devices_poll(struct file *file, poll_table *wait)
4907+{
4908+ int state = input_devices_state;
4909+ poll_wait(file, &input_devices_poll_wait, wait);
4910+ if (state != input_devices_state)
4911+ return POLLIN | POLLRDNORM;
4912+ return 0;
4913+}
4914+
4915+static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
4916+{
4917+ struct input_dev *dev = input_dev;
4918+ struct input_handle *handle;
4919+
4920+ off_t at = 0;
4921+ int i, len, cnt = 0;
4922+
4923+ while (dev) {
4924+
4925+ len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
4926+ dev->idbus, dev->idvendor, dev->idproduct, dev->idversion);
4927+
4928+ len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
4929+ len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
4930+ len += sprintf(buf + len, "D: Drivers=");
4931+
4932+ handle = dev->handle;
4933+
4934+ while (handle) {
4935+ len += sprintf(buf + len, "%s ", handle->name);
4936+ handle = handle->dnext;
4937+ }
4938+
4939+ len += sprintf(buf + len, "\n");
4940+
4941+ SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
4942+ SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
4943+ SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
4944+ SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
4945+ SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
4946+ SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
4947+ SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
4948+ SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF);
4949+
4950+ len += sprintf(buf + len, "\n");
4951+
4952+ at += len;
4953+
4954+ if (at >= pos) {
4955+ if (!*start) {
4956+ *start = buf + (pos - (at - len));
4957+ cnt = at - pos;
4958+ } else cnt += len;
4959+ buf += len;
4960+ if (cnt >= count)
4961+ break;
4962+ }
4963+
4964+ dev = dev->next;
4965+ }
4966+
4967+ if (!dev) *eof = 1;
4968+
4969+ return (count > cnt) ? cnt : count;
4970+}
4971+
4972+static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
4973+{
4974+ struct input_handler *handler = input_handler;
4975+
4976+ off_t at = 0;
4977+ int len = 0, cnt = 0;
4978+ int i = 0;
4979+
4980+ while (handler) {
4981+
4982+ if (handler->fops)
4983+ len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n",
4984+ i++, handler->name, handler->minor);
4985+ else
4986+ len = sprintf(buf, "N: Number=%d Name=%s\n",
4987+ i++, handler->name);
4988+
4989+ at += len;
4990+
4991+ if (at >= pos) {
4992+ if (!*start) {
4993+ *start = buf + (pos - (at - len));
4994+ cnt = at - pos;
4995+ } else cnt += len;
4996+ buf += len;
4997+ if (cnt >= count)
4998+ break;
4999+ }
5000+
5001+ handler = handler->next;
5002+ }
5003+
5004+ if (!handler) *eof = 1;
5005+
5006+ return (count > cnt) ? cnt : count;
5007+}
5008+
5009+#endif
5010+
5011 static int __init input_init(void)
5012 {
5013+ struct proc_dir_entry *entry;
5014+
5015+#ifdef CONFIG_PROC_FS
5016+ proc_bus_input_dir = proc_mkdir("input", proc_bus);
5017+ proc_bus_input_dir->owner = THIS_MODULE;
5018+ entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL);
5019+ entry->owner = THIS_MODULE;
5020+ entry->proc_fops->poll = input_devices_poll;
5021+ entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL);
5022+ entry->owner = THIS_MODULE;
5023+#endif
5024 if (devfs_register_chrdev(INPUT_MAJOR, "input", &input_fops)) {
5025 printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
5026 return -EBUSY;
5027 }
5028+
5029 input_devfs_handle = devfs_mk_dir(NULL, "input", NULL);
5030+
5031 return 0;
5032 }
5033
5034 static void __exit input_exit(void)
5035 {
5036+#ifdef CONFIG_PROC_FS
5037+ remove_proc_entry("devices", proc_bus_input_dir);
5038+ remove_proc_entry("handlers", proc_bus_input_dir);
5039+ remove_proc_entry("input", proc_bus);
5040+#endif
5041 devfs_unregister(input_devfs_handle);
5042 if (devfs_unregister_chrdev(INPUT_MAJOR, "input"))
5043 printk(KERN_ERR "input: can't unregister char major %d", INPUT_MAJOR);
5044diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/input/joydev.c linux-modified/drivers/input/joydev.c
5045--- linux-vanilla/drivers/input/joydev.c Mon Feb 3 20:47:45 2003
5046+++ linux-modified/drivers/input/joydev.c Tue Feb 4 21:26:33 2003
5047@@ -1,12 +1,10 @@
5048 /*
5049- * $Id$
5050+ * $Id$
5051 *
5052- * Copyright (c) 1999-2000 Vojtech Pavlik
5053+ * Copyright (c) 1999-2001 Vojtech Pavlik
5054 * Copyright (c) 1999 Colin Van Dyke
5055 *
5056 * Joystick device driver for the input driver suite.
5057- *
5058- * Sponsored by SuSE and Intel
5059 */
5060
5061 /*
5062@@ -25,8 +23,8 @@
5063 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5064 *
5065 * Should you need to contact me, the author, you can do so either by
5066- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
5067- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
5068+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
5069+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
5070 */
5071
5072 #include <asm/io.h>
5073@@ -46,6 +44,11 @@
5074 #include <linux/init.h>
5075 #include <linux/smp_lock.h>
5076
5077+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
5078+MODULE_DESCRIPTION("Joystick device interfaces");
5079+MODULE_SUPPORTED_DEVICE("input/js");
5080+MODULE_LICENSE("GPL");
5081+
5082 #define JOYDEV_MINOR_BASE 0
5083 #define JOYDEV_MINORS 32
5084 #define JOYDEV_BUFFER_SIZE 64
5085@@ -56,6 +59,7 @@
5086 int exist;
5087 int open;
5088 int minor;
5089+ char name[16];
5090 struct input_handle handle;
5091 wait_queue_head_t wait;
5092 devfs_handle_t devfs;
5093@@ -84,11 +88,6 @@
5094
5095 static struct joydev *joydev_table[JOYDEV_MINORS];
5096
5097-MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
5098-MODULE_DESCRIPTION("Joystick device driver");
5099-MODULE_LICENSE("GPL");
5100-MODULE_SUPPORTED_DEVICE("input/js");
5101-
5102 static int joydev_correct(int value, struct js_corr *corr)
5103 {
5104 switch (corr->type) {
5105@@ -167,7 +166,6 @@
5106 struct joydev_list *list = file->private_data;
5107 struct joydev_list **listptr;
5108
5109- lock_kernel();
5110 listptr = &list->joydev->list;
5111 joydev_fasync(-1, file, 0);
5112
5113@@ -186,7 +184,6 @@
5114 }
5115
5116 kfree(list);
5117- unlock_kernel();
5118
5119 return 0;
5120 }
5121@@ -254,10 +251,15 @@
5122 if (list->head == list->tail && list->startup == joydev->nabs + joydev->nkey) {
5123
5124 add_wait_queue(&list->joydev->wait, &wait);
5125- current->state = TASK_INTERRUPTIBLE;
5126+ set_current_state(TASK_INTERRUPTIBLE);
5127
5128 while (list->head == list->tail) {
5129
5130+ if (!joydev->exist) {
5131+ retval = -ENODEV;
5132+ break;
5133+ }
5134+
5135 if (file->f_flags & O_NONBLOCK) {
5136 retval = -EAGAIN;
5137 break;
5138@@ -270,7 +272,7 @@
5139 schedule();
5140 }
5141
5142- current->state = TASK_RUNNING;
5143+ set_current_state(TASK_RUNNING);
5144 remove_wait_queue(&list->joydev->wait, &wait);
5145 }
5146
5147@@ -329,6 +331,8 @@
5148 struct input_dev *dev = joydev->handle.dev;
5149 int i;
5150
5151+ if (!joydev->exist) return -ENODEV;
5152+
5153 switch (cmd) {
5154
5155 case JS_SET_CAL:
5156@@ -410,16 +414,11 @@
5157 fasync: joydev_fasync,
5158 };
5159
5160-static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev)
5161+static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
5162 {
5163 struct joydev *joydev;
5164 int i, j, t, minor;
5165
5166- if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_ABS, dev->evbit) &&
5167- (test_bit(ABS_X, dev->absbit) || test_bit(ABS_Y, dev->absbit)) &&
5168- (test_bit(BTN_TRIGGER, dev->keybit) || test_bit(BTN_A, dev->keybit)
5169- || test_bit(BTN_1, dev->keybit)))) return NULL;
5170-
5171 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
5172 if (minor == JOYDEV_MINORS) {
5173 printk(KERN_ERR "joydev: no more free joydev devices\n");
5174@@ -435,12 +434,13 @@
5175 joydev->minor = minor;
5176 joydev_table[minor] = joydev;
5177
5178+ sprintf(joydev->name, "js%d", minor);
5179+
5180 joydev->handle.dev = dev;
5181+ joydev->handle.name = joydev->name;
5182 joydev->handle.handler = handler;
5183 joydev->handle.private = joydev;
5184
5185- joydev->exist = 1;
5186-
5187 for (i = 0; i < ABS_MAX; i++)
5188 if (test_bit(i, dev->absbit)) {
5189 joydev->absmap[i] = joydev->nabs;
5190@@ -484,6 +484,8 @@
5191
5192 // printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number);
5193
5194+ joydev->exist = 1;
5195+
5196 return &joydev->handle;
5197 }
5198
5199@@ -502,12 +504,35 @@
5200 }
5201 }
5202
5203+static struct input_device_id joydev_ids[] = {
5204+ {
5205+ flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
5206+ evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
5207+ absbit: { BIT(ABS_X) },
5208+ },
5209+ {
5210+ flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
5211+ evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
5212+ absbit: { BIT(ABS_WHEEL) },
5213+ },
5214+ {
5215+ flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
5216+ evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
5217+ absbit: { BIT(ABS_THROTTLE) },
5218+ },
5219+ { }, /* Terminating entry */
5220+};
5221+
5222+MODULE_DEVICE_TABLE(input, joydev_ids);
5223+
5224 static struct input_handler joydev_handler = {
5225 event: joydev_event,
5226 connect: joydev_connect,
5227 disconnect: joydev_disconnect,
5228 fops: &joydev_fops,
5229 minor: JOYDEV_MINOR_BASE,
5230+ name: "joydev",
5231+ id_table: joydev_ids,
5232 };
5233
5234 static int __init joydev_init(void)
5235diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/input/keybdev.c linux-modified/drivers/input/keybdev.c
5236--- linux-vanilla/drivers/input/keybdev.c Thu Oct 11 18:14:32 2001
5237+++ linux-modified/drivers/input/keybdev.c Mon Jan 6 16:48:20 2003
5238@@ -177,20 +177,11 @@
5239 tasklet_schedule(&keyboard_tasklet);
5240 }
5241
5242-static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev)
5243+static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id* id)
5244 {
5245 struct input_handle *handle;
5246 int i;
5247
5248- if (!test_bit(EV_KEY, dev->evbit))
5249- return NULL;
5250-
5251- for (i = KEY_RESERVED; i < BTN_MISC; i++)
5252- if (test_bit(i, dev->keybit)) break;
5253-
5254- if (i == BTN_MISC)
5255- return NULL;
5256-
5257 if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
5258 return NULL;
5259 memset(handle, 0, sizeof(struct input_handle));
5260@@ -212,10 +203,25 @@
5261 kfree(handle);
5262 }
5263
5264+static struct input_device_id keybdev_ids[] = {
5265+ /* If it's got an "esc" key, it's a keyboard */
5266+ {
5267+ flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
5268+ evbit: { BIT(EV_KEY) | BIT(EV_REL) },
5269+ keybit: { BIT(KEY_ESC) },
5270+ },
5271+
5272+ { }, /* Terminating entry */
5273+};
5274+
5275+MODULE_DEVICE_TABLE(input, keybdev_ids);
5276+
5277 static struct input_handler keybdev_handler = {
5278 event: keybdev_event,
5279 connect: keybdev_connect,
5280 disconnect: keybdev_disconnect,
5281+ name: "keybdev",
5282+ id_table: keybdev_ids,
5283 };
5284
5285 static int __init keybdev_init(void)
5286diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/input/mousedev.c linux-modified/drivers/input/mousedev.c
5287--- linux-vanilla/drivers/input/mousedev.c Sun Sep 30 21:26:05 2001
5288+++ linux-modified/drivers/input/mousedev.c Mon Jan 6 16:48:20 2003
5289@@ -1,11 +1,9 @@
5290 /*
5291- * $Id$
5292+ * $Id$
5293 *
5294- * Copyright (c) 1999-2000 Vojtech Pavlik
5295+ * Copyright (c) 1999-2001 Vojtech Pavlik
5296 *
5297- * Input driver to ImExPS/2 device driver module.
5298- *
5299- * Sponsored by SuSE
5300+ * Input driver to ExplorerPS/2 device driver module.
5301 */
5302
5303 /*
5304@@ -24,8 +22,8 @@
5305 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5306 *
5307 * Should you need to contact me, the author, you can do so either by
5308- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
5309- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
5310+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
5311+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
5312 */
5313
5314 #define MOUSEDEV_MINOR_BASE 32
5315@@ -41,6 +39,10 @@
5316 #include <linux/smp_lock.h>
5317 #include <linux/random.h>
5318
5319+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
5320+MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
5321+MODULE_LICENSE("GPL");
5322+
5323 #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
5324 #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
5325 #endif
5326@@ -52,6 +54,7 @@
5327 int exist;
5328 int open;
5329 int minor;
5330+ char name[16];
5331 wait_queue_head_t wait;
5332 struct mousedev_list *list;
5333 struct input_handle handle;
5334@@ -89,8 +92,6 @@
5335 struct mousedev_list *list;
5336 int index, size;
5337
5338- add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
5339-
5340 while (*mousedev) {
5341 list = (*mousedev)->list;
5342 while (list) {
5343@@ -101,13 +102,23 @@
5344 switch (code) {
5345 case ABS_X:
5346 size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
5347- list->dx += (value * xres - list->oldx) / size;
5348- list->oldx += list->dx * size;
5349+ if (size != 0) {
5350+ list->dx += (value * xres - list->oldx) / size;
5351+ list->oldx += list->dx * size;
5352+ } else {
5353+ list->dx += value - list->oldx;
5354+ list->oldx += list->dx;
5355+ }
5356 break;
5357 case ABS_Y:
5358 size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
5359- list->dy -= (value * yres - list->oldy) / size;
5360- list->oldy -= list->dy * size;
5361+ if (size != 0) {
5362+ list->dy -= (value * yres - list->oldy) / size;
5363+ list->oldy -= list->dy * size;
5364+ } else {
5365+ list->dy -= value - list->oldy;
5366+ list->oldy -= list->dy;
5367+ }
5368 break;
5369 }
5370 break;
5371@@ -170,7 +181,6 @@
5372 struct mousedev_list *list = file->private_data;
5373 struct mousedev_list **listptr;
5374
5375- lock_kernel();
5376 listptr = &list->mousedev->list;
5377 mousedev_fasync(-1, file, 0);
5378
5379@@ -208,7 +218,6 @@
5380 }
5381
5382 kfree(list);
5383- unlock_kernel();
5384
5385 return 0;
5386 }
5387@@ -216,7 +225,14 @@
5388 static int mousedev_open(struct inode * inode, struct file * file)
5389 {
5390 struct mousedev_list *list;
5391- int i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE;
5392+ int i;
5393+
5394+#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5395+ if (major(inode->i_rdev) == MISC_MAJOR))
5396+ i = MOUSEDEV_MIX;
5397+ else
5398+#endif
5399+ i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE;
5400
5401 if (i >= MOUSEDEV_MINORS || !mousedev_table[i])
5402 return -ENODEV;
5403@@ -346,7 +362,7 @@
5404 if (!list->ready && !list->buffer) {
5405
5406 add_wait_queue(&list->mousedev->wait, &wait);
5407- current->state = TASK_INTERRUPTIBLE;
5408+ set_current_state(TASK_INTERRUPTIBLE);
5409
5410 while (!list->ready) {
5411
5412@@ -362,7 +378,7 @@
5413 schedule();
5414 }
5415
5416- current->state = TASK_RUNNING;
5417+ set_current_state(TASK_RUNNING);
5418 remove_wait_queue(&list->mousedev->wait, &wait);
5419 }
5420
5421@@ -403,19 +419,11 @@
5422 fasync: mousedev_fasync,
5423 };
5424
5425-static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev)
5426+static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
5427 {
5428 struct mousedev *mousedev;
5429 int minor = 0;
5430
5431- if (!test_bit(EV_KEY, dev->evbit) ||
5432- (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit)))
5433- return NULL;
5434-
5435- if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) &&
5436- (!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit)))
5437- return NULL;
5438-
5439 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
5440 if (minor == MOUSEDEV_MINORS) {
5441 printk(KERN_ERR "mousedev: no more free mousedev devices\n");
5442@@ -427,11 +435,12 @@
5443 memset(mousedev, 0, sizeof(struct mousedev));
5444 init_waitqueue_head(&mousedev->wait);
5445
5446- mousedev->exist = 1;
5447 mousedev->minor = minor;
5448 mousedev_table[minor] = mousedev;
5449+ sprintf(mousedev->name, "mouse%d", minor);
5450
5451 mousedev->handle.dev = dev;
5452+ mousedev->handle.name = mousedev->name;
5453 mousedev->handle.handler = handler;
5454 mousedev->handle.private = mousedev;
5455
5456@@ -440,7 +449,7 @@
5457 if (mousedev_mix.open)
5458 input_open_device(&mousedev->handle);
5459
5460-// printk(KERN_INFO "mouse%d: PS/2 mouse device for input%d\n", minor, dev->number);
5461+ mousedev->exist = 1;
5462
5463 return &mousedev->handle;
5464 }
5465@@ -461,6 +470,26 @@
5466 kfree(mousedev);
5467 }
5468 }
5469+
5470+static struct input_device_id mousedev_ids[] = {
5471+ {
5472+ flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
5473+ evbit: { BIT(EV_KEY) | BIT(EV_REL) },
5474+ keybit: { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
5475+ relbit: { BIT(REL_X) | BIT(REL_Y) },
5476+ }, /* A mouse like device, at least one button, two relative axes */
5477+
5478+ {
5479+ flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
5480+ evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
5481+ keybit: { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
5482+ absbit: { BIT(ABS_X) | BIT(ABS_Y) },
5483+ }, /* A tablet like device, at least touch detection, two absolute axes */
5484+
5485+ { }, /* Terminating entry */
5486+};
5487+
5488+MODULE_DEVICE_TABLE(input, mousedev_ids);
5489
5490 static struct input_handler mousedev_handler = {
5491 event: mousedev_event,
5492@@ -468,7 +497,15 @@
5493 disconnect: mousedev_disconnect,
5494 fops: &mousedev_fops,
5495 minor: MOUSEDEV_MINOR_BASE,
5496+ name: "mousedev",
5497+ id_table: mousedev_ids,
5498+};
5499+
5500+#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5501+static struct miscdevice psaux_mouse = {
5502+ PSMOUSE_MINOR, "psaux", &mousedev_fops
5503 };
5504+#endif
5505
5506 static int __init mousedev_init(void)
5507 {
5508@@ -480,6 +517,9 @@
5509 mousedev_mix.exist = 1;
5510 mousedev_mix.minor = MOUSEDEV_MIX;
5511 mousedev_mix.devfs = input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);
5512+#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5513+ misc_register(&psaux_mouse)
5514+#endif
5515
5516 printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
5517
5518@@ -488,16 +528,15 @@
5519
5520 static void __exit mousedev_exit(void)
5521 {
5522+#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5523+ misc_deregister(&psaux_mouse)
5524+#endif
5525 input_unregister_minor(mousedev_mix.devfs);
5526 input_unregister_handler(&mousedev_handler);
5527 }
5528
5529 module_init(mousedev_init);
5530 module_exit(mousedev_exit);
5531-
5532-MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
5533-MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver");
5534-MODULE_LICENSE("GPL");
5535
5536 MODULE_PARM(xres, "i");
5537 MODULE_PARM_DESC(xres, "Horizontal screen resolution");
5538diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/Config.in linux-modified/drivers/usb/Config.in
5539--- linux-vanilla/drivers/usb/Config.in Mon Jan 6 15:58:08 2003
5540+++ linux-modified/drivers/usb/Config.in Mon Jan 6 16:48:20 2003
5541@@ -62,6 +62,8 @@
5542 fi
5543 dep_mbool ' HID input layer support' CONFIG_USB_HIDINPUT $CONFIG_INPUT $CONFIG_USB_HID
5544 dep_mbool ' /dev/hiddev raw HID device support' CONFIG_USB_HIDDEV $CONFIG_USB_HID
5545+ dep_mbool ' Force feedback support (EXPERIMENTAL)' CONFIG_HID_FF $CONFIG_USB_HID $CONFIG_EXPERIMENTAL
5546+ dep_mbool ' Logitech WingMan 3D devices (EXPERIMENTAL)' CONFIG_LOGITECH_FF $CONFIG_HID_FF $CONFIG_EXPERIMENTAL
5547 if [ "$CONFIG_USB_HID" != "y" ]; then
5548 dep_tristate ' USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
5549 dep_tristate ' USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
5550diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/Makefile linux-modified/drivers/usb/Makefile
5551--- linux-vanilla/drivers/usb/Makefile Mon Jan 6 15:58:08 2003
5552+++ linux-modified/drivers/usb/Makefile Mon Jan 6 16:48:20 2003
5553@@ -34,6 +34,14 @@
5554 hid-objs += hid-input.o
5555 endif
5556
5557+ifeq ($(CONFIG_HID_FF),y)
5558+ hid-objs += hid-ff.o
5559+endif
5560+
5561+ifeq ($(CONFIG_LOGITECH_FF),y)
5562+ hid-objs += hid-lgff.o
5563+endif
5564+
5565 # Object file lists.
5566
5567 obj-y :=
5568diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/fixp-arith.h linux-modified/drivers/usb/fixp-arith.h
5569--- linux-vanilla/drivers/usb/fixp-arith.h Thu Jan 1 02:00:00 1970
5570+++ linux-modified/drivers/usb/fixp-arith.h Sun Mar 9 17:01:24 2003
5571@@ -0,0 +1,100 @@
5572+#ifndef _FIXP_ARITH_H
5573+#define _FIXP_ARITH_H
5574+
5575+/*
5576+ * $$
5577+ *
5578+ * Simplistic fixed-point arithmetics.
5579+ * Hmm, I'm probably duplicating some code :(
5580+ *
5581+ * Copyright (c) 2002 Johann Deneux
5582+ */
5583+
5584+/*
5585+ * This program is free software; you can redistribute it and/or modify
5586+ * it under the terms of the GNU General Public License as published by
5587+ * the Free Software Foundation; either version 2 of the License, or
5588+ * (at your option) any later version.
5589+ *
5590+ * This program is distributed in the hope that it will be useful,
5591+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5592+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5593+ * GNU General Public License for more details.
5594+ *
5595+ * You should have received a copy of the GNU General Public License
5596+ * along with this program; if not, write to the Free Software
5597+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5598+ *
5599+ * Should you need to contact me, the author, you can do so by
5600+ * e-mail - mail your message to <deneux@ifrance.com>
5601+ */
5602+
5603+#include <linux/types.h>
5604+
5605+// The type representing fixed-point values
5606+typedef s16 fixp_t;
5607+
5608+#define FRAC_N 8
5609+#define FRAC_MASK ((1<<FRAC_N)-1)
5610+
5611+// Not to be used directly. Use fixp_{cos,sin}
5612+fixp_t cos_table[45] = {
5613+ 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8,
5614+ 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD,
5615+ 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1,
5616+ 0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078,
5617+ 0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035,
5618+ 0x002C, 0x0023, 0x001A, 0x0011, 0x0008
5619+};
5620+
5621+
5622+/* a: 123 -> 123.0 */
5623+inline fixp_t fixp_new(s16 a)
5624+{
5625+ return a<<FRAC_N;
5626+}
5627+
5628+/* a: 0xFFFF -> -1.0
5629+ 0x8000 -> 1.0
5630+ 0x0000 -> 0.0
5631+*/
5632+inline fixp_t fixp_new16(s16 a)
5633+{
5634+ return ((s32)a)>>(16-FRAC_N);
5635+}
5636+
5637+inline int fixp_toint(fixp_t x)
5638+{
5639+ return x>>FRAC_N;
5640+}
5641+
5642+inline fixp_t fixp_cos(unsigned int degrees)
5643+{
5644+ int quadrant = (degrees / 90) & 3;
5645+ unsigned int i = degrees % 90;
5646+
5647+ if (quadrant == 1 || quadrant == 3) {
5648+ i = 89 - i;
5649+ }
5650+
5651+ i >>= 1;
5652+
5653+ return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
5654+}
5655+
5656+inline fixp_t fixp_sin(unsigned int degrees)
5657+{
5658+ return -fixp_cos(degrees + 90);
5659+}
5660+
5661+inline fixp_t fixp_mult(fixp_t a, fixp_t b)
5662+{
5663+ return ((s32)(a*b))>>FRAC_N;
5664+}
5665+
5666+inline fixp_t fixp_div(fixp_t a, fixp_t b)
5667+{
5668+ return (a/b)<<FRAC_N;
5669+}
5670+
5671+#endif
5672diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hid-core.c linux-modified/drivers/usb/hid-core.c
5673--- linux-vanilla/drivers/usb/hid-core.c Mon Jan 6 15:58:08 2003
5674+++ linux-modified/drivers/usb/hid-core.c Mon Jan 13 23:41:59 2003
5675@@ -1,12 +1,10 @@
5676 /*
5677- * $Id$
5678+ * $Id$
5679 *
5680 * Copyright (c) 1999 Andreas Gal
5681 * Copyright (c) 2000-2001 Vojtech Pavlik
5682 *
5683 * USB HID support for Linux
5684- *
5685- * Sponsored by SuSE
5686 */
5687
5688 /*
5689@@ -25,8 +23,8 @@
5690 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5691 *
5692 * Should you need to contact me, the author, you can do so either by
5693- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
5694- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
5695+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
5696+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
5697 */
5698
5699 #include <linux/module.h>
5700@@ -47,15 +45,19 @@
5701 #include <linux/usb.h>
5702
5703 #include "hid.h"
5704+#ifdef CONFIG_USB_HIDDEV
5705 #include <linux/hiddev.h>
5706+#endif
5707+
5708
5709 /*
5710 * Version Information
5711 */
5712
5713-#define DRIVER_VERSION "v1.8.1"
5714-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>"
5715-#define DRIVER_DESC "USB HID support drivers"
5716+#define DRIVER_VERSION "v1.31"
5717+#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik <vojtech@ucw.cz>"
5718+#define DRIVER_DESC "USB HID core driver"
5719+#define DRIVER_LICENSE "GPL"
5720
5721 static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
5722 "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
5723@@ -206,7 +208,6 @@
5724 dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
5725 return -1;
5726 }
5727-
5728 usages = parser->local.usage_index;
5729
5730 offset = report->size;
5731@@ -322,7 +323,7 @@
5732 return 0;
5733
5734 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
5735- parser->global.unit_exponent = item_udata(item);
5736+ parser->global.unit_exponent = item_sdata(item);
5737 return 0;
5738
5739 case HID_GLOBAL_ITEM_TAG_UNIT:
5740@@ -507,8 +508,6 @@
5741
5742 for (n = 0; n < report->maxfield; n++)
5743 kfree(report->field[n]);
5744- if (report->data)
5745- kfree(report->data);
5746 kfree(report);
5747 }
5748
5749@@ -520,6 +519,10 @@
5750 {
5751 unsigned i,j;
5752
5753+#ifdef CONFIG_HID_FF
5754+ hid_ff_exit(device);
5755+#endif
5756+
5757 for (i = 0; i < HID_REPORT_TYPES; i++) {
5758 struct hid_report_enum *report_enum = device->report_enum + i;
5759
5760@@ -537,60 +540,64 @@
5761 * items, though they are not used yet.
5762 */
5763
5764-static __u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
5765+static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
5766 {
5767- if ((end - start) > 0) {
5768+ u8 b;
5769
5770- __u8 b = *start++;
5771- item->type = (b >> 2) & 3;
5772- item->tag = (b >> 4) & 15;
5773+ if ((end - start) <= 0)
5774+ return NULL;
5775
5776- if (item->tag == HID_ITEM_TAG_LONG) {
5777+ b = *start++;
5778
5779- item->format = HID_ITEM_FORMAT_LONG;
5780+ item->type = (b >> 2) & 3;
5781+ item->tag = (b >> 4) & 15;
5782
5783- if ((end - start) >= 2) {
5784+ if (item->tag == HID_ITEM_TAG_LONG) {
5785
5786- item->size = *start++;
5787- item->tag = *start++;
5788+ item->format = HID_ITEM_FORMAT_LONG;
5789
5790- if ((end - start) >= item->size) {
5791- item->data.longdata = start;
5792- start += item->size;
5793- return start;
5794- }
5795- }
5796- } else {
5797+ if ((end - start) < 2)
5798+ return NULL;
5799
5800- item->format = HID_ITEM_FORMAT_SHORT;
5801- item->size = b & 3;
5802- switch (item->size) {
5803-
5804- case 0:
5805- return start;
5806-
5807- case 1:
5808- if ((end - start) >= 1) {
5809- item->data.u8 = *start++;
5810- return start;
5811- }
5812- break;
5813-
5814- case 2:
5815- if ((end - start) >= 2) {
5816- item->data.u16 = le16_to_cpu( get_unaligned(((__u16*)start)++));
5817- return start;
5818- }
5819-
5820- case 3:
5821- item->size++;
5822- if ((end - start) >= 4) {
5823- item->data.u32 = le32_to_cpu( get_unaligned(((__u32*)start)++));
5824- return start;
5825- }
5826- }
5827- }
5828+ item->size = *start++;
5829+ item->tag = *start++;
5830+
5831+ if ((end - start) < item->size)
5832+ return NULL;
5833+
5834+ item->data.longdata = start;
5835+ start += item->size;
5836+ return start;
5837+ }
5838+
5839+ item->format = HID_ITEM_FORMAT_SHORT;
5840+ item->size = b & 3;
5841+
5842+ switch (item->size) {
5843+
5844+ case 0:
5845+ return start;
5846+
5847+ case 1:
5848+ if ((end - start) < 1)
5849+ return NULL;
5850+ item->data.u8 = *start++;
5851+ return start;
5852+
5853+ case 2:
5854+ if ((end - start) < 2)
5855+ return NULL;
5856+ item->data.u16 = le16_to_cpu(get_unaligned(((__u16*)start)++));
5857+ return start;
5858+
5859+ case 3:
5860+ item->size++;
5861+ if ((end - start) < 4)
5862+ return NULL;
5863+ item->data.u32 = le32_to_cpu(get_unaligned(((__u32*)start)++));
5864+ return start;
5865 }
5866+
5867 return NULL;
5868 }
5869
5870@@ -637,12 +644,14 @@
5871
5872 end = start + size;
5873 while ((start = fetch_item(start, end, &item)) != 0) {
5874+
5875 if (item.format != HID_ITEM_FORMAT_SHORT) {
5876 dbg("unexpected long global item");
5877 hid_free_device(device);
5878 kfree(parser);
5879 return NULL;
5880 }
5881+
5882 if (dispatch_type[item.type](parser, &item)) {
5883 dbg("item %u %u %u %u parsing failed\n",
5884 item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
5885@@ -735,11 +744,24 @@
5886 hid_dump_input(usage, value);
5887 if (hid->claimed & HID_CLAIMED_INPUT)
5888 hidinput_hid_event(hid, field, usage, value);
5889- if (hid->claimed & HID_CLAIMED_HIDDEV)
5890- hiddev_hid_event(hid, usage->hid, value);
5891+#ifdef CONFIG_USB_HIDDEV
5892+ if (hid->claimed & HID_CLAIMED_HIDDEV) {
5893+ struct hiddev_usage_ref uref;
5894+ unsigned type = field->report_type;
5895+ uref.report_type =
5896+ (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
5897+ ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
5898+ ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
5899+ uref.report_id = field->report->id;
5900+ uref.field_index = field->index;
5901+ uref.usage_index = (usage - field->usage);
5902+ uref.usage_code = usage->hid;
5903+ uref.value = value;
5904+ hiddev_hid_event(hid, &uref);
5905+ }
5906+#endif
5907 }
5908
5909-
5910 /*
5911 * Analyse a received field, and fetch the data from it. The field
5912 * content is stored for next report processing (we do differential
5913@@ -794,9 +816,12 @@
5914 memcpy(field->value, value, count * sizeof(__s32));
5915 }
5916
5917-static int hid_input_report(int type, u8 *data, int len, struct hid_device *hid)
5918+static int hid_input_report(int type, struct urb *urb)
5919 {
5920+ struct hid_device *hid = urb->context;
5921 struct hid_report_enum *report_enum = hid->report_enum + type;
5922+ u8 *data = urb->transfer_buffer;
5923+ int len = urb->actual_length;
5924 struct hid_report *report;
5925 int n, size;
5926
5927@@ -815,95 +840,46 @@
5928 len--;
5929 }
5930
5931- if (!(report = report_enum->report_id_hash[n])) {
5932- dbg("undefined report_id %d received", n);
5933-#ifdef DEBUG
5934- printk(KERN_DEBUG __FILE__ ": report (size %u) = ", len);
5935- for (n = 0; n < len; n++)
5936- printk(" %02x", data[n]);
5937- printk("\n");
5938+#ifdef DEBUG_DATA
5939+ {
5940+ int i;
5941+ printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len);
5942+ for (i = 0; i < n; i++)
5943+ printk(" %02x", data[i]);
5944+ printk("\n");
5945+ }
5946 #endif
5947
5948+ if (!(report = report_enum->report_id_hash[n])) {
5949+ dbg("undefined report_id %d received", n);
5950 return -1;
5951 }
5952
5953 size = ((report->size - 1) >> 3) + 1;
5954
5955 if (len < size) {
5956-
5957- if (size <= 8) {
5958- dbg("report %d is too short, (%d < %d)", report->id, len, size);
5959- return -1;
5960- }
5961-
5962- /*
5963- * Some low-speed devices have large reports and maxpacketsize 8.
5964- * We buffer the data in that case and parse it when we got it all.
5965- * Works only for unnumbered reports. Doesn't make sense for numbered
5966- * reports anyway - then they don't need to be large.
5967- */
5968-
5969- if (!report->data)
5970- if (!(report->data = kmalloc(size, GFP_ATOMIC))) {
5971- dbg("couldn't allocate report buffer");
5972- return -1;
5973- }
5974-
5975- if (report->idx + len > size) {
5976- dbg("report data buffer overflow");
5977- report->idx = 0;
5978- return -1;
5979- }
5980-
5981- memcpy(report->data + report->idx, data, len);
5982- report->idx += len;
5983-
5984- if (report->idx < size)
5985- return 0;
5986-
5987- data = report->data;
5988+ dbg("report %d is too short, (%d < %d)", report->id, len, size);
5989+ return -1;
5990 }
5991
5992 for (n = 0; n < report->maxfield; n++)
5993 hid_input_field(hid, report->field[n], data);
5994
5995- report->idx = 0;
5996 return 0;
5997 }
5998
5999 /*
6000- * Interrupt input handler.
6001+ * Input interrupt completion handler.
6002 */
6003
6004-static void hid_irq(struct urb *urb)
6005+static void hid_irq_in(struct urb *urb)
6006 {
6007 if (urb->status) {
6008- dbg("nonzero status in irq %d", urb->status);
6009+ dbg("nonzero status in input irq %d", urb->status);
6010 return;
6011 }
6012
6013- hid_input_report(HID_INPUT_REPORT, urb->transfer_buffer, urb->actual_length, urb->context);
6014-}
6015-
6016-/*
6017- * hid_read_report() reads in report values without waiting for an irq urb.
6018- */
6019-
6020-void hid_read_report(struct hid_device *hid, struct hid_report *report)
6021-{
6022- int len = ((report->size - 1) >> 3) + 1 + hid->report_enum[report->type].numbered;
6023- u8 data[len];
6024- int read;
6025-
6026- if (hid->quirks & HID_QUIRK_NOGET)
6027- return;
6028-
6029- if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) {
6030- dbg("reading report type %d id %d failed len %d read %d", report->type + 1, report->id, len, read);
6031- return;
6032- }
6033-
6034- hid_input_report(report->type, data, len, hid);
6035+ hid_input_report(HID_INPUT_REPORT, urb);
6036 }
6037
6038 /*
6039@@ -949,7 +925,8 @@
6040 hid_dump_input(field->usage + offset, value);
6041
6042 if (offset >= field->report_count) {
6043- dbg("offset exceeds report_count");
6044+ dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
6045+ hid_dump_field(field, 8);
6046 return -1;
6047 }
6048 if (field->logical_minimum < 0) {
6049@@ -958,11 +935,6 @@
6050 return -1;
6051 }
6052 }
6053- if ( (value > field->logical_maximum)
6054- || (value < field->logical_minimum)) {
6055- dbg("value %d is invalid", value);
6056- return -1;
6057- }
6058 field->value[offset] = value;
6059 return 0;
6060 }
6061@@ -986,14 +958,54 @@
6062 return -1;
6063 }
6064
6065+/*
6066+ * Find a report with a specified HID usage.
6067+ */
6068+
6069+int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type)
6070+{
6071+ struct hid_report_enum *report_enum = hid->report_enum + type;
6072+ struct list_head *list = report_enum->report_list.next;
6073+ int i, j;
6074+
6075+ while (list != &report_enum->report_list) {
6076+ *report = (struct hid_report *) list;
6077+ list = list->next;
6078+ for (i = 0; i < (*report)->maxfield; i++) {
6079+ struct hid_field *field = (*report)->field[i];
6080+ for (j = 0; j < field->maxusage; j++)
6081+ if (field->logical == wanted_usage)
6082+ return j;
6083+ }
6084+ }
6085+ return -1;
6086+}
6087+
6088+int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field)
6089+{
6090+ int i, j;
6091+
6092+ for (i = 0; i < report->maxfield; i++) {
6093+ *field = report->field[i];
6094+ for (j = 0; j < (*field)->maxusage; j++)
6095+ if ((*field)->usage[j].hid == wanted_usage)
6096+ return j;
6097+ }
6098+
6099+ return -1;
6100+}
6101+
6102 static int hid_submit_out(struct hid_device *hid)
6103 {
6104- hid->urbout.transfer_buffer_length = le16_to_cpup(&hid->out[hid->outtail].dr.wLength);
6105- hid->urbout.transfer_buffer = hid->out[hid->outtail].buffer;
6106- hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr);
6107- hid->urbout.dev = hid->dev;
6108+ struct hid_report *report;
6109
6110- if (usb_submit_urb(&hid->urbout)) {
6111+ report = hid->out[hid->outtail];
6112+
6113+ hid_output_report(report, hid->outbuf);
6114+ hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1;
6115+ hid->urbout->dev = hid->dev;
6116+
6117+ if (usb_submit_urb(hid->urbout)) {
6118 err("usb_submit_urb(out) failed");
6119 return -1;
6120 }
6121@@ -1001,33 +1013,168 @@
6122 return 0;
6123 }
6124
6125+static int hid_submit_ctrl(struct hid_device *hid)
6126+{
6127+ struct hid_report *report;
6128+ unsigned char dir;
6129+
6130+ report = hid->ctrl[hid->ctrltail].report;
6131+ dir = hid->ctrl[hid->ctrltail].dir;
6132+
6133+ if (dir == USB_DIR_OUT)
6134+ hid_output_report(report, hid->ctrlbuf);
6135+
6136+ hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && (dir != USB_DIR_OUT));
6137+ hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0);
6138+ hid->urbctrl->dev = hid->dev;
6139+
6140+ hid->dr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
6141+ hid->dr.bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
6142+ hid->dr.wValue = ((report->type + 1) << 8) | report->id;
6143+ hid->dr.wIndex = cpu_to_le16(hid->ifnum);
6144+ hid->dr.wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length);
6145+
6146+ if (usb_submit_urb(hid->urbctrl)) {
6147+ err("usb_submit_urb(ctrl) failed");
6148+ return -1;
6149+ }
6150+
6151+ return 0;
6152+}
6153+
6154+/*
6155+ * Output interrupt completion handler.
6156+ */
6157+
6158+static void hid_irq_out(struct urb *urb)
6159+{
6160+ struct hid_device *hid = urb->context;
6161+ unsigned long flags;
6162+
6163+ if (urb->status)
6164+ warn("output irq status %d received", urb->status);
6165+
6166+ spin_lock_irqsave(&hid->outlock, flags);
6167+
6168+ hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
6169+
6170+ if (hid->outhead != hid->outtail) {
6171+ hid_submit_out(hid);
6172+ spin_unlock_irqrestore(&hid->outlock, flags);
6173+ return;
6174+ }
6175+
6176+ clear_bit(HID_OUT_RUNNING, &hid->iofl);
6177+
6178+ spin_unlock_irqrestore(&hid->outlock, flags);
6179+
6180+ wake_up(&hid->wait);
6181+}
6182+
6183+/*
6184+ * Control pipe completion handler.
6185+ */
6186+
6187 static void hid_ctrl(struct urb *urb)
6188 {
6189 struct hid_device *hid = urb->context;
6190+ unsigned long flags;
6191
6192 if (urb->status)
6193 warn("ctrl urb status %d received", urb->status);
6194
6195- hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6196+ spin_lock_irqsave(&hid->ctrllock, flags);
6197
6198- if (hid->outhead != hid->outtail)
6199- hid_submit_out(hid);
6200+ if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
6201+ hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb);
6202+
6203+ hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6204+
6205+ if (hid->ctrlhead != hid->ctrltail) {
6206+ hid_submit_ctrl(hid);
6207+ spin_unlock_irqrestore(&hid->ctrllock, flags);
6208+ return;
6209+ }
6210+
6211+ clear_bit(HID_CTRL_RUNNING, &hid->iofl);
6212+
6213+ spin_unlock_irqrestore(&hid->ctrllock, flags);
6214+
6215+ wake_up(&hid->wait);
6216 }
6217
6218-void hid_write_report(struct hid_device *hid, struct hid_report *report)
6219+void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
6220 {
6221- hid_output_report(report, hid->out[hid->outhead].buffer);
6222+ int head;
6223+ unsigned long flags;
6224
6225- hid->out[hid->outhead].dr.wValue = cpu_to_le16(0x200 | report->id);
6226- hid->out[hid->outhead].dr.wLength = cpu_to_le16((report->size + 7) >> 3);
6227+ if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
6228
6229- hid->outhead = (hid->outhead + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6230+ spin_lock_irqsave(&hid->outlock, flags);
6231
6232- if (hid->outhead == hid->outtail)
6233- hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6234+ if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) {
6235+ spin_unlock_irqrestore(&hid->outlock, flags);
6236+ warn("output queue full");
6237+ return;
6238+ }
6239
6240- if (hid->urbout.status != -EINPROGRESS)
6241- hid_submit_out(hid);
6242+ hid->out[hid->outhead] = report;
6243+ hid->outhead = head;
6244+
6245+ if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl))
6246+ hid_submit_out(hid);
6247+
6248+ spin_unlock_irqrestore(&hid->outlock, flags);
6249+ return;
6250+ }
6251+
6252+ spin_lock_irqsave(&hid->ctrllock, flags);
6253+
6254+ if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) {
6255+ spin_unlock_irqrestore(&hid->ctrllock, flags);
6256+ warn("control queue full");
6257+ return;
6258+ }
6259+
6260+ hid->ctrl[hid->ctrlhead].report = report;
6261+ hid->ctrl[hid->ctrlhead].dir = dir;
6262+ hid->ctrlhead = head;
6263+
6264+ if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl))
6265+ hid_submit_ctrl(hid);
6266+
6267+ spin_unlock_irqrestore(&hid->ctrllock, flags);
6268+}
6269+
6270+int hid_wait_io(struct hid_device *hid)
6271+{
6272+ DECLARE_WAITQUEUE(wait, current);
6273+ int timeout = 10*HZ;
6274+
6275+ set_current_state(TASK_UNINTERRUPTIBLE);
6276+ add_wait_queue(&hid->wait, &wait);
6277+
6278+ while (timeout && (test_bit(HID_CTRL_RUNNING, &hid->iofl) ||
6279+ test_bit(HID_OUT_RUNNING, &hid->iofl)))
6280+ timeout = schedule_timeout(timeout);
6281+
6282+ set_current_state(TASK_RUNNING);
6283+ remove_wait_queue(&hid->wait, &wait);
6284+
6285+ if (!timeout) {
6286+ dbg("timeout waiting for ctrl or out queue to clear");
6287+ return -1;
6288+ }
6289+
6290+ return 0;
6291+}
6292+#define USB_CTRL_GET_TIMEOUT 5
6293+static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
6294+ unsigned char type, void *buf, int size)
6295+{
6296+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
6297+ USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
6298+ (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT);
6299 }
6300
6301 int hid_open(struct hid_device *hid)
6302@@ -1035,9 +1182,9 @@
6303 if (hid->open++)
6304 return 0;
6305
6306- hid->urb.dev = hid->dev;
6307+ hid->urbin->dev = hid->dev;
6308
6309- if (usb_submit_urb(&hid->urb))
6310+ if (usb_submit_urb(hid->urbin))
6311 return -EIO;
6312
6313 return 0;
6314@@ -1046,81 +1193,83 @@
6315 void hid_close(struct hid_device *hid)
6316 {
6317 if (!--hid->open)
6318- usb_unlink_urb(&hid->urb);
6319+ usb_unlink_urb(hid->urbin);
6320 }
6321
6322 /*
6323- * Initialize all readable reports
6324+ * Initialize all reports
6325 */
6326+#define USB_CTRL_SET_TIMEOUT 5
6327 void hid_init_reports(struct hid_device *hid)
6328 {
6329- int i;
6330- struct hid_report *report;
6331 struct hid_report_enum *report_enum;
6332+ struct hid_report *report;
6333 struct list_head *list;
6334+ int len;
6335+ int err, ret;
6336
6337- for (i = 0; i < HID_REPORT_TYPES; i++) {
6338- if (i == HID_FEATURE_REPORT || i == HID_INPUT_REPORT) {
6339- report_enum = hid->report_enum + i;
6340- list = report_enum->report_list.next;
6341- while (list != &report_enum->report_list) {
6342- report = (struct hid_report *) list;
6343- hid_read_report(hid, report);
6344- usb_set_idle(hid->dev, hid->ifnum, 0, report->id);
6345- list = list->next;
6346- }
6347- }
6348+ report_enum = hid->report_enum + HID_INPUT_REPORT;
6349+ list = report_enum->report_list.next;
6350+ while (list != &report_enum->report_list) {
6351+ report = (struct hid_report *) list;
6352+ hid_submit_report(hid, report, USB_DIR_IN);
6353+ list = list->next;
6354+ }
6355+
6356+ report_enum = hid->report_enum + HID_FEATURE_REPORT;
6357+ list = report_enum->report_list.next;
6358+ while (list != &report_enum->report_list) {
6359+ report = (struct hid_report *) list;
6360+ hid_submit_report(hid, report, USB_DIR_IN);
6361+ list = list->next;
6362+ }
6363+
6364+ err = 0;
6365+ while ((ret = hid_wait_io(hid))) {
6366+ err |= ret;
6367+ if (test_bit(HID_CTRL_RUNNING, &hid->iofl))
6368+ usb_unlink_urb(hid->urbctrl);
6369+ if (test_bit(HID_OUT_RUNNING, &hid->iofl))
6370+ usb_unlink_urb(hid->urbout);
6371+ }
6372+
6373+ if (err)
6374+ warn("timeout initializing reports\n");
6375+
6376+ report_enum = hid->report_enum + HID_INPUT_REPORT;
6377+ list = report_enum->report_list.next;
6378+ while (list != &report_enum->report_list) {
6379+ report = (struct hid_report *) list;
6380+ len = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
6381+ if (len > hid->urbin->transfer_buffer_length)
6382+ hid->urbin->transfer_buffer_length = len < HID_BUFFER_SIZE ? len : HID_BUFFER_SIZE;
6383+ usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
6384+ 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id,
6385+ hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
6386+ list = list->next;
6387 }
6388 }
6389
6390 #define USB_VENDOR_ID_WACOM 0x056a
6391-#define USB_DEVICE_ID_WACOM_PENPARTNER 0x0000
6392 #define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
6393 #define USB_DEVICE_ID_WACOM_INTUOS 0x0020
6394-#define USB_DEVICE_ID_WACOM_PL 0x0030
6395-#define USB_DEVICE_ID_WACOM_INTUOS2 0x0041
6396-
6397-#define USB_VENDOR_ID_ATEN 0x0557
6398-#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
6399-#define USB_DEVICE_ID_ATEN_CS124U 0x2202
6400-#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
6401-#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
6402
6403 #define USB_VENDOR_ID_GRIFFIN 0x077d
6404-#define USB_DEVICE_ID_POWERMATE 0x0410 /* Griffin PowerMate */
6405-#define USB_DEVICE_ID_SOUNDKNOB 0x04AA /* Griffin SoundKnob */
6406+#define USB_DEVICE_ID_POWERMATE 0x0410
6407+#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
6408
6409 struct hid_blacklist {
6410 __u16 idVendor;
6411 __u16 idProduct;
6412- unsigned quirks;
6413 } hid_blacklist[] = {
6414- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
6415- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
6416- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
6417- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE },
6418- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE },
6419- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE },
6420- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE },
6421- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3, HID_QUIRK_IGNORE },
6422- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4, HID_QUIRK_IGNORE },
6423- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL, HID_QUIRK_IGNORE },
6424- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 1, HID_QUIRK_IGNORE },
6425- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 2, HID_QUIRK_IGNORE },
6426- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
6427- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
6428- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
6429- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2, HID_QUIRK_IGNORE },
6430- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
6431- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
6432- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
6433- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
6434- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
6435- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
6436- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
6437- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
6438- { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
6439- { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
6440+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE },
6441+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS },
6442+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1},
6443+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2},
6444+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3},
6445+ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4},
6446+ { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE },
6447+ { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB },
6448 { 0, 0 }
6449 };
6450
6451@@ -1129,26 +1278,23 @@
6452 struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
6453 struct hid_descriptor *hdesc;
6454 struct hid_device *hid;
6455- unsigned quirks = 0, rsize = 0;
6456+ unsigned rsize = 0;
6457+ u8 *rdesc;
6458 char *buf;
6459 int n;
6460
6461 for (n = 0; hid_blacklist[n].idVendor; n++)
6462 if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) &&
6463- (hid_blacklist[n].idProduct == dev->descriptor.idProduct))
6464- quirks = hid_blacklist[n].quirks;
6465-
6466- if (quirks & HID_QUIRK_IGNORE)
6467- return NULL;
6468+ (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL;
6469
6470- if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
6471- usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc))) {
6472+ if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->bNumEndpoints) ||
6473+ usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
6474 dbg("class descriptor not present\n");
6475 return NULL;
6476 }
6477
6478 for (n = 0; n < hdesc->bNumDescriptors; n++)
6479- if (hdesc->desc[n].bDescriptorType == USB_DT_REPORT)
6480+ if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
6481 rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
6482
6483 if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
6484@@ -1156,118 +1302,158 @@
6485 return NULL;
6486 }
6487
6488- {
6489- __u8 rdesc[rsize];
6490+ if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
6491+ dbg("couldn't allocate rdesc memory");
6492+ return NULL;
6493+ }
6494
6495- if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) {
6496- dbg("reading report descriptor failed");
6497- return NULL;
6498- }
6499+ if ((n = hid_get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
6500+ dbg("reading report descriptor failed");
6501+ kfree(rdesc);
6502+ return NULL;
6503+ }
6504
6505 #ifdef DEBUG_DATA
6506- printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
6507- for (n = 0; n < rsize; n++)
6508- printk(" %02x", (unsigned) rdesc[n]);
6509- printk("\n");
6510+ printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
6511+ for (n = 0; n < rsize; n++)
6512+ printk(" %02x", (unsigned) rdesc[n]);
6513+ printk("\n");
6514 #endif
6515
6516- if (!(hid = hid_parse_report(rdesc, rsize))) {
6517- dbg("parsing report descriptor failed");
6518- return NULL;
6519- }
6520+ if (!(hid = hid_parse_report(rdesc, rsize))) {
6521+ dbg("parsing report descriptor failed");
6522+ kfree(rdesc);
6523+ return NULL;
6524 }
6525
6526- hid->quirks = quirks;
6527+ kfree(rdesc);
6528
6529 for (n = 0; n < interface->bNumEndpoints; n++) {
6530
6531 struct usb_endpoint_descriptor *endpoint = &interface->endpoint[n];
6532- int pipe, maxp;
6533+ int pipe;
6534
6535 if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */
6536 continue;
6537
6538- if (!(endpoint->bEndpointAddress & 0x80)) /* Not an input endpoint */
6539- continue;
6540-
6541- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
6542- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
6543-
6544- FILL_INT_URB(&hid->urb, dev, pipe, hid->buffer, maxp > 32 ? 32 : maxp, hid_irq, hid, endpoint->bInterval);
6545-
6546- break;
6547+ if (endpoint->bEndpointAddress & USB_DIR_IN) {
6548+ if (hid->urbin)
6549+ continue;
6550+ if (!(hid->urbin = usb_alloc_urb(0)))
6551+ goto fail;
6552+ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
6553+ FILL_INT_URB(hid->urbin, dev, pipe, hid->inbuf, 0, hid_irq_in, hid, endpoint->bInterval);
6554+ } else {
6555+ if (hid->urbout)
6556+ continue;
6557+ if (!(hid->urbout = usb_alloc_urb(0)))
6558+ goto fail;
6559+ pipe = usb_sndbulkpipe(dev, endpoint->bEndpointAddress);
6560+ FILL_BULK_URB(hid->urbout, dev, pipe, hid->outbuf, 0, hid_irq_out, hid);
6561+ hid->urbout->transfer_flags |= USB_ASYNC_UNLINK;
6562+ }
6563 }
6564
6565- if (n == interface->bNumEndpoints) {
6566- dbg("couldn't find an input interrupt endpoint");
6567- hid_free_device(hid);
6568- return NULL;
6569+ if (!hid->urbin) {
6570+ err("couldn't find an input interrupt endpoint");
6571+ goto fail;
6572 }
6573
6574+ init_waitqueue_head(&hid->wait);
6575+
6576+ hid->outlock = SPIN_LOCK_UNLOCKED;
6577+ hid->ctrllock = SPIN_LOCK_UNLOCKED;
6578+
6579 hid->version = hdesc->bcdHID;
6580 hid->country = hdesc->bCountryCode;
6581 hid->dev = dev;
6582 hid->ifnum = interface->bInterfaceNumber;
6583
6584- for (n = 0; n < HID_CONTROL_FIFO_SIZE; n++) {
6585- hid->out[n].dr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
6586- hid->out[n].dr.bRequest = USB_REQ_SET_REPORT;
6587- hid->out[n].dr.wIndex = cpu_to_le16(hid->ifnum);
6588- }
6589-
6590 hid->name[0] = 0;
6591
6592- if (!(buf = kmalloc(63, GFP_KERNEL)))
6593- return NULL;
6594+ if (!(buf = kmalloc(64, GFP_KERNEL)))
6595+ goto fail;
6596
6597- if (usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) {
6598+ if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) {
6599 strcat(hid->name, buf);
6600- if (usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
6601+ if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0)
6602 sprintf(hid->name, "%s %s", hid->name, buf);
6603 } else
6604 sprintf(hid->name, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
6605
6606- kfree(buf);
6607+ usb_make_path(dev, buf, 63);
6608+ sprintf(hid->phys, "%s/input%d", buf, ifnum);
6609
6610- FILL_CONTROL_URB(&hid->urbout, dev, usb_sndctrlpipe(dev, 0),
6611- (void*) &hid->out[0].dr, hid->out[0].buffer, 1, hid_ctrl, hid);
6612+ if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
6613+ hid->uniq[0] = 0;
6614
6615-/*
6616- * Some devices don't like this and crash. I don't know of any devices
6617- * needing this, so it is disabled for now.
6618- */
6619+ kfree(buf);
6620
6621-#if 0
6622- if (interface->bInterfaceSubClass == 1)
6623- usb_set_protocol(dev, hid->ifnum, 1);
6624-#endif
6625+ hid->urbctrl = usb_alloc_urb(0);
6626+ FILL_CONTROL_URB(hid->urbctrl, dev, 0, (void*) &hid->dr, hid->ctrlbuf, 1, hid_ctrl, hid);
6627+ hid->urbctrl->transfer_flags |= USB_ASYNC_UNLINK;
6628
6629 return hid;
6630+
6631+fail:
6632+ hid_free_device(hid);
6633+ if (hid->urbin) usb_free_urb(hid->urbin);
6634+ if (hid->urbout) usb_free_urb(hid->urbout);
6635+ if (hid->urbctrl) usb_free_urb(hid->urbctrl);
6636+
6637+ return NULL;
6638 }
6639
6640 static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
6641 const struct usb_device_id *id)
6642 {
6643 struct hid_device *hid;
6644+ char path[64];
6645 int i;
6646 char *c;
6647
6648 dbg("HID probe called for ifnum %d", ifnum);
6649
6650- if (!(hid = usb_hid_configure(dev, ifnum)))
6651+ if (!(hid = usb_hid_configure(dev, ifnum))) {
6652+ err("usb_hid_configure failed");
6653 return NULL;
6654+ }
6655
6656 hid_init_reports(hid);
6657 hid_dump_device(hid);
6658
6659+#ifdef CONFIG_HID_FF
6660+ switch (hid_ff_init(hid)) {
6661+ case 0:
6662+ break;
6663+
6664+ case -ENOSYS:
6665+ info("No force feedback support for this hid device");
6666+ break;
6667+
6668+ default:
6669+ err("hid_ff_init failed");
6670+ hid_free_device(hid);
6671+ return NULL;
6672+ }
6673+#endif
6674+
6675 if (!hidinput_connect(hid))
6676 hid->claimed |= HID_CLAIMED_INPUT;
6677+#ifdef CONFIG_USB_HIDDEV
6678 if (!hiddev_connect(hid))
6679 hid->claimed |= HID_CLAIMED_HIDDEV;
6680+#endif
6681+
6682+ if (!hid->claimed) {
6683+ hid_free_device(hid);
6684+ return NULL;
6685+ }
6686+
6687 printk(KERN_INFO);
6688
6689 if (hid->claimed & HID_CLAIMED_INPUT)
6690- printk("input%d", hid->input.number);
6691+ printk("input");
6692 if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV))
6693 printk(",");
6694 if (hid->claimed & HID_CLAIMED_HIDDEV)
6695@@ -1280,9 +1466,10 @@
6696 break;
6697 }
6698
6699- printk(": USB HID v%x.%02x %s [%s] on usb%d:%d.%d\n",
6700- hid->version >> 8, hid->version & 0xff, c, hid->name,
6701- dev->bus->busnum, dev->devnum, ifnum);
6702+ usb_make_path(dev, path, 63);
6703+
6704+ printk(": USB HID v%x.%02x %s [%s] on %s\n",
6705+ hid->version >> 8, hid->version & 0xff, c, hid->name, path);
6706
6707 return hid;
6708 }
6709@@ -1291,12 +1478,22 @@
6710 {
6711 struct hid_device *hid = ptr;
6712
6713- dbg("cleanup called");
6714- usb_unlink_urb(&hid->urb);
6715+ usb_unlink_urb(hid->urbin);
6716+ usb_unlink_urb(hid->urbout);
6717+ usb_unlink_urb(hid->urbctrl);
6718+
6719 if (hid->claimed & HID_CLAIMED_INPUT)
6720 hidinput_disconnect(hid);
6721+#ifdef CONFIG_USB_HIDDEV
6722 if (hid->claimed & HID_CLAIMED_HIDDEV)
6723 hiddev_disconnect(hid);
6724+#endif
6725+
6726+ usb_free_urb(hid->urbin);
6727+ usb_free_urb(hid->urbctrl);
6728+ if (hid->urbout)
6729+ usb_free_urb(hid->urbout);
6730+
6731 hid_free_device(hid);
6732 }
6733
6734@@ -1317,23 +1514,26 @@
6735
6736 static int __init hid_init(void)
6737 {
6738+#ifdef CONFIG_USB_HIDDEV
6739 hiddev_init();
6740+#endif
6741 usb_register(&hid_driver);
6742- info(DRIVER_VERSION " " DRIVER_AUTHOR);
6743- info(DRIVER_DESC);
6744+ info(DRIVER_VERSION ":" DRIVER_DESC);
6745
6746 return 0;
6747 }
6748
6749 static void __exit hid_exit(void)
6750 {
6751+#ifdef CONFIG_USB_HIDDEV
6752 hiddev_exit();
6753+#endif
6754 usb_deregister(&hid_driver);
6755 }
6756
6757 module_init(hid_init);
6758 module_exit(hid_exit);
6759
6760-MODULE_AUTHOR( DRIVER_AUTHOR );
6761-MODULE_DESCRIPTION( DRIVER_DESC );
6762-MODULE_LICENSE("GPL");
6763+MODULE_AUTHOR(DRIVER_AUTHOR);
6764+MODULE_DESCRIPTION(DRIVER_DESC);
6765+MODULE_LICENSE(DRIVER_LICENSE);
6766diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hid-debug.h linux-modified/drivers/usb/hid-debug.h
6767--- linux-vanilla/drivers/usb/hid-debug.h Thu Sep 13 00:34:06 2001
6768+++ linux-modified/drivers/usb/hid-debug.h Mon Jan 6 16:48:21 2003
6769@@ -1,12 +1,10 @@
6770 /*
6771- * $Id$
6772+ * $Id$
6773 *
6774 * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
6775- * (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
6776+ * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
6777 *
6778 * Some debug stuff for the HID parser.
6779- *
6780- * Sponsored by SuSE
6781 */
6782
6783 /*
6784@@ -25,8 +23,8 @@
6785 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6786 *
6787 * Should you need to contact me, the author, you can do so either by
6788- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
6789- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
6790+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
6791+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
6792 */
6793
6794 struct hid_usage_entry {
6795@@ -36,6 +34,7 @@
6796 };
6797
6798 static struct hid_usage_entry hid_usage_table[] = {
6799+ { 0, 0, "Undefined" },
6800 { 1, 0, "GenericDesktop" },
6801 {0, 0x01, "Pointer"},
6802 {0, 0x02, "Mouse"},
6803@@ -87,6 +86,7 @@
6804 { 7, 0, "Keyboard" },
6805 { 8, 0, "LED" },
6806 { 9, 0, "Button" },
6807+ { 10, 0, "Ordinal" },
6808 { 12, 0, "Hotkey" },
6809 { 13, 0, "Digitizers" },
6810 {0, 0x01, "Digitizer"},
6811@@ -112,6 +112,112 @@
6812 {0, 0x45, "Eraser"},
6813 {0, 0x46, "TabletPick"},
6814 { 15, 0, "PhysicalInterfaceDevice" },
6815+ {0, 0x00, "Undefined"},
6816+ {0, 0x01, "Physical_Interface_Device"},
6817+ {0, 0x20, "Normal"},
6818+ {0, 0x21, "Set_Effect_Report"},
6819+ {0, 0x22, "Effect_Block_Index"},
6820+ {0, 0x23, "Parameter_Block_Offset"},
6821+ {0, 0x24, "ROM_Flag"},
6822+ {0, 0x25, "Effect_Type"},
6823+ {0, 0x26, "ET_Constant_Force"},
6824+ {0, 0x27, "ET_Ramp"},
6825+ {0, 0x28, "ET_Custom_Force_Data"},
6826+ {0, 0x30, "ET_Square"},
6827+ {0, 0x31, "ET_Sine"},
6828+ {0, 0x32, "ET_Triangle"},
6829+ {0, 0x33, "ET_Sawtooth_Up"},
6830+ {0, 0x34, "ET_Sawtooth_Down"},
6831+ {0, 0x40, "ET_Spring"},
6832+ {0, 0x41, "ET_Damper"},
6833+ {0, 0x42, "ET_Inertia"},
6834+ {0, 0x43, "ET_Friction"},
6835+ {0, 0x50, "Duration"},
6836+ {0, 0x51, "Sample_Period"},
6837+ {0, 0x52, "Gain"},
6838+ {0, 0x53, "Trigger_Button"},
6839+ {0, 0x54, "Trigger_Repeat_Interval"},
6840+ {0, 0x55, "Axes_Enable"},
6841+ {0, 0x56, "Direction_Enable"},
6842+ {0, 0x57, "Direction"},
6843+ {0, 0x58, "Type_Specific_Block_Offset"},
6844+ {0, 0x59, "Block_Type"},
6845+ {0, 0x5A, "Set_Envelope_Report"},
6846+ {0, 0x5B, "Attack_Level"},
6847+ {0, 0x5C, "Attack_Time"},
6848+ {0, 0x5D, "Fade_Level"},
6849+ {0, 0x5E, "Fade_Time"},
6850+ {0, 0x5F, "Set_Condition_Report"},
6851+ {0, 0x60, "CP_Offset"},
6852+ {0, 0x61, "Positive_Coefficient"},
6853+ {0, 0x62, "Negative_Coefficient"},
6854+ {0, 0x63, "Positive_Saturation"},
6855+ {0, 0x64, "Negative_Saturation"},
6856+ {0, 0x65, "Dead_Band"},
6857+ {0, 0x66, "Download_Force_Sample"},
6858+ {0, 0x67, "Isoch_Custom_Force_Enable"},
6859+ {0, 0x68, "Custom_Force_Data_Report"},
6860+ {0, 0x69, "Custom_Force_Data"},
6861+ {0, 0x6A, "Custom_Force_Vendor_Defined_Data"},
6862+ {0, 0x6B, "Set_Custom_Force_Report"},
6863+ {0, 0x6C, "Custom_Force_Data_Offset"},
6864+ {0, 0x6D, "Sample_Count"},
6865+ {0, 0x6E, "Set_Periodic_Report"},
6866+ {0, 0x6F, "Offset"},
6867+ {0, 0x70, "Magnitude"},
6868+ {0, 0x71, "Phase"},
6869+ {0, 0x72, "Period"},
6870+ {0, 0x73, "Set_Constant_Force_Report"},
6871+ {0, 0x74, "Set_Ramp_Force_Report"},
6872+ {0, 0x75, "Ramp_Start"},
6873+ {0, 0x76, "Ramp_End"},
6874+ {0, 0x77, "Effect_Operation_Report"},
6875+ {0, 0x78, "Effect_Operation"},
6876+ {0, 0x79, "Op_Effect_Start"},
6877+ {0, 0x7A, "Op_Effect_Start_Solo"},
6878+ {0, 0x7B, "Op_Effect_Stop"},
6879+ {0, 0x7C, "Loop_Count"},
6880+ {0, 0x7D, "Device_Gain_Report"},
6881+ {0, 0x7E, "Device_Gain"},
6882+ {0, 0x7F, "PID_Pool_Report"},
6883+ {0, 0x80, "RAM_Pool_Size"},
6884+ {0, 0x81, "ROM_Pool_Size"},
6885+ {0, 0x82, "ROM_Effect_Block_Count"},
6886+ {0, 0x83, "Simultaneous_Effects_Max"},
6887+ {0, 0x84, "Pool_Alignment"},
6888+ {0, 0x85, "PID_Pool_Move_Report"},
6889+ {0, 0x86, "Move_Source"},
6890+ {0, 0x87, "Move_Destination"},
6891+ {0, 0x88, "Move_Length"},
6892+ {0, 0x89, "PID_Block_Load_Report"},
6893+ {0, 0x8B, "Block_Load_Status"},
6894+ {0, 0x8C, "Block_Load_Success"},
6895+ {0, 0x8D, "Block_Load_Full"},
6896+ {0, 0x8E, "Block_Load_Error"},
6897+ {0, 0x8F, "Block_Handle"},
6898+ {0, 0x90, "PID_Block_Free_Report"},
6899+ {0, 0x91, "Type_Specific_Block_Handle"},
6900+ {0, 0x92, "PID_State_Report"},
6901+ {0, 0x94, "Effect_Playing"},
6902+ {0, 0x95, "PID_Device_Control_Report"},
6903+ {0, 0x96, "PID_Device_Control"},
6904+ {0, 0x97, "DC_Enable_Actuators"},
6905+ {0, 0x98, "DC_Disable_Actuators"},
6906+ {0, 0x99, "DC_Stop_All_Effects"},
6907+ {0, 0x9A, "DC_Device_Reset"},
6908+ {0, 0x9B, "DC_Device_Pause"},
6909+ {0, 0x9C, "DC_Device_Continue"},
6910+ {0, 0x9F, "Device_Paused"},
6911+ {0, 0xA0, "Actuators_Enabled"},
6912+ {0, 0xA4, "Safety_Switch"},
6913+ {0, 0xA5, "Actuator_Override_Switch"},
6914+ {0, 0xA6, "Actuator_Power"},
6915+ {0, 0xA7, "Start_Delay"},
6916+ {0, 0xA8, "Parameter_Block_Size"},
6917+ {0, 0xA9, "Device_Managed_Pool"},
6918+ {0, 0xAA, "Shared_Parameter_Blocks"},
6919+ {0, 0xAB, "Create_New_Effect_Report"},
6920+ {0, 0xAC, "RAM_Pool_Available"},
6921 { 0, 0, NULL }
6922 };
6923
6924@@ -176,7 +282,50 @@
6925 tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
6926 }
6927 if (field->unit) {
6928- tab(n); printk("Unit(%u)\n", field->unit);
6929+ char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
6930+ char *units[5][8] = {
6931+ { "None", "None", "None", "None", "None", "None", "None", "None" },
6932+ { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
6933+ { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
6934+ { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
6935+ { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
6936+ };
6937+
6938+ int i;
6939+ int sys;
6940+ __u32 data = field->unit;
6941+
6942+ /* First nibble tells us which system we're in. */
6943+ sys = data & 0xf;
6944+ data >>= 4;
6945+
6946+ if(sys > 4) {
6947+ tab(n); printk("Unit(Invalid)\n");
6948+ }
6949+ else {
6950+ int earlier_unit = 0;
6951+
6952+ tab(n); printk("Unit(%s : ", systems[sys]);
6953+
6954+ for (i=1 ; i<sizeof(__u32)*2 ; i++) {
6955+ char nibble = data & 0xf;
6956+ data >>= 4;
6957+ if (nibble != 0) {
6958+ if(earlier_unit++ > 0)
6959+ printk("*");
6960+ printk("%s", units[sys][i]);
6961+ if(nibble != 1) {
6962+ /* This is a _signed_ nibble(!) */
6963+
6964+ int val = nibble & 0x7;
6965+ if(nibble & 0x08)
6966+ val = -((0x7 & ~val) +1);
6967+ printk("^%d", val);
6968+ }
6969+ }
6970+ }
6971+ printk(")\n");
6972+ }
6973 }
6974 tab(n); printk("Report Size(%u)\n", field->report_size);
6975 tab(n); printk("Report Count(%u)\n", field->report_count);
6976diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hid-ff.c linux-modified/drivers/usb/hid-ff.c
6977--- linux-vanilla/drivers/usb/hid-ff.c Thu Jan 1 02:00:00 1970
6978+++ linux-modified/drivers/usb/hid-ff.c Mon Jan 6 16:48:21 2003
6979@@ -0,0 +1,69 @@
6980+/*
6981+ * Force feedback support for hid devices.
6982+ * Not all hid devices use the same protocol. For example, some use PID,
6983+ * other use their own proprietary procotol.
6984+ *
6985+ * Copyright (c) 2002 Johann Deneux
6986+ */
6987+
6988+/*
6989+ * This program is free software; you can redistribute it and/or modify
6990+ * it under the terms of the GNU General Public License as published by
6991+ * the Free Software Foundation; either version 2 of the License, or
6992+ * (at your option) any later version.
6993+ *
6994+ * This program is distributed in the hope that it will be useful,
6995+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6996+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6997+ * GNU General Public License for more details.
6998+ *
6999+ * You should have received a copy of the GNU General Public License
7000+ * along with this program; if not, write to the Free Software
7001+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7002+ *
7003+ * Should you need to contact me, the author, you can do so by
7004+ * e-mail - mail your message to <deneux@ifrance.com>
7005+ */
7006+
7007+#include <linux/input.h>
7008+
7009+#define DEBUG
7010+#include <linux/usb.h>
7011+
7012+#include "hid.h"
7013+
7014+/* Drivers' initializing functions */
7015+extern int hid_lgff_init(struct hid_device* hid);
7016+extern int hid_pid_init(struct hid_device* hid);
7017+
7018+/* Each hid force feedback driver must provide an init function.
7019+ It must return 1 if the driver does not handle this device,
7020+ 0 if it could and the initialization itself went smoothly,
7021+ <0 if the driver should have been able to handle the device, but failed
7022+*/
7023+static int (*inits[])(struct hid_device*) = {
7024+#ifdef CONFIG_LOGITECH_FF
7025+ hid_lgff_init,
7026+#endif
7027+#ifdef CONFIG_HID_PID
7028+ hid_pid_init,
7029+#endif
7030+ NULL
7031+};
7032+
7033+int hid_ff_init(struct hid_device* hid)
7034+{
7035+ int i;
7036+ int status;
7037+
7038+ for (i=0; inits[i]; ++i) {
7039+ switch (status = inits[i](hid)) {
7040+ case 0: return 0; // Device handled and init ok
7041+ case 1: break; // Device not handled
7042+ default: return status; // Device handled, init failed
7043+ }
7044+ }
7045+
7046+ dbg("hid_ff_init could not find initializer");
7047+ return -ENOSYS;
7048+}
7049diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hid-input.c linux-modified/drivers/usb/hid-input.c
7050--- linux-vanilla/drivers/usb/hid-input.c Sun Nov 11 20:09:37 2001
7051+++ linux-modified/drivers/usb/hid-input.c Mon Jan 6 16:48:21 2003
7052@@ -1,11 +1,9 @@
7053 /*
7054- * $Id$
7055+ * $Id$
7056 *
7057 * Copyright (c) 2000-2001 Vojtech Pavlik
7058 *
7059- * USB HID to Linux Input mapping module
7060- *
7061- * Sponsored by SuSE
7062+ * USB HID to Linux Input mapping
7063 */
7064
7065 /*
7066@@ -24,13 +22,12 @@
7067 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7068 *
7069 * Should you need to contact me, the author, you can do so either by
7070- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
7071- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
7072+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
7073+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
7074 */
7075
7076 #include <linux/module.h>
7077 #include <linux/slab.h>
7078-#include <linux/init.h>
7079 #include <linux/kernel.h>
7080 #include <linux/input.h>
7081 #include <linux/usb.h>
7082@@ -61,12 +58,13 @@
7083 static struct {
7084 __s32 x;
7085 __s32 y;
7086-} hid_hat_to_axis[] = {{0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
7087+} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
7088
7089 static void hidinput_configure_usage(struct hid_device *device, struct hid_field *field, struct hid_usage *usage)
7090 {
7091 struct input_dev *input = &device->input;
7092 int max;
7093+ int is_abs = 0;
7094 unsigned long *bit;
7095
7096 switch (usage->hid & HID_USAGE_PAGE) {
7097@@ -198,6 +196,7 @@
7098
7099 case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
7100
7101+ set_bit(EV_REP, input->evbit);
7102 switch (usage->hid & HID_USAGE) {
7103 case 0x000: usage->code = 0; break;
7104 case 0x034: usage->code = KEY_SLEEP; break;
7105@@ -205,14 +204,21 @@
7106 case 0x08a: usage->code = KEY_WWW; break;
7107 case 0x095: usage->code = KEY_HELP; break;
7108
7109+ case 0x0b0: usage->code = KEY_PLAY; break;
7110+ case 0x0b1: usage->code = KEY_PAUSE; break;
7111+ case 0x0b2: usage->code = KEY_RECORD; break;
7112+ case 0x0b3: usage->code = KEY_FASTFORWARD; break;
7113 case 0x0b4: usage->code = KEY_REWIND; break;
7114 case 0x0b5: usage->code = KEY_NEXTSONG; break;
7115 case 0x0b6: usage->code = KEY_PREVIOUSSONG; break;
7116 case 0x0b7: usage->code = KEY_STOPCD; break;
7117 case 0x0b8: usage->code = KEY_EJECTCD; break;
7118 case 0x0cd: usage->code = KEY_PLAYPAUSE; break;
7119-
7120+ case 0x0e0: is_abs = 1;
7121+ usage->code = ABS_VOLUME;
7122+ break;
7123 case 0x0e2: usage->code = KEY_MUTE; break;
7124+ case 0x0e5: usage->code = KEY_BASSBOOST; break;
7125 case 0x0e9: usage->code = KEY_VOLUMEUP; break;
7126 case 0x0ea: usage->code = KEY_VOLUMEDOWN; break;
7127
7128@@ -220,7 +226,6 @@
7129 case 0x18a: usage->code = KEY_MAIL; break;
7130 case 0x192: usage->code = KEY_CALC; break;
7131 case 0x194: usage->code = KEY_FILE; break;
7132-
7133 case 0x21a: usage->code = KEY_UNDO; break;
7134 case 0x21b: usage->code = KEY_COPY; break;
7135 case 0x21c: usage->code = KEY_CUT; break;
7136@@ -235,6 +240,34 @@
7137 case 0x22a: usage->code = KEY_BOOKMARKS; break;
7138
7139 default: usage->code = KEY_UNKNOWN; break;
7140+ }
7141+
7142+ if (is_abs) {
7143+ usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
7144+ } else {
7145+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
7146+ }
7147+ break;
7148+
7149+ case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
7150+
7151+ set_bit(EV_REP, input->evbit);
7152+ switch (usage->hid & HID_USAGE) {
7153+ case 0x021: usage->code = KEY_PRINT; break;
7154+ case 0x070: usage->code = KEY_HP; break;
7155+ case 0x071: usage->code = KEY_CAMERA; break;
7156+ case 0x072: usage->code = KEY_SOUND; break;
7157+ case 0x073: usage->code = KEY_QUESTION; break;
7158+
7159+ case 0x080: usage->code = KEY_EMAIL; break;
7160+ case 0x081: usage->code = KEY_CHAT; break;
7161+ case 0x082: usage->code = KEY_SEARCH; break;
7162+ case 0x083: usage->code = KEY_CONNECT; break;
7163+ case 0x084: usage->code = KEY_FINANCE; break;
7164+ case 0x085: usage->code = KEY_SPORT; break;
7165+ case 0x086: usage->code = KEY_SHOP; break;
7166+
7167+ default: usage->code = KEY_UNKNOWN; break;
7168
7169 }
7170
7171@@ -344,16 +377,28 @@
7172 static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
7173 {
7174 struct hid_device *hid = dev->private;
7175- struct hid_field *field = NULL;
7176- int offset;
7177
7178- if ((offset = hid_find_field(hid, type, code, &field)) == -1) {
7179- warn("event field not found");
7180- return -1;
7181+ warn("hid input event");
7182+
7183+#ifdef CONFIG_HID_FF
7184+ if (type == EV_FF) {
7185+ return hid_ff_event(hid, dev, type, code, value);
7186 }
7187+#else
7188+ if (0) {}
7189+#endif
7190+ else {
7191+ struct hid_field *field = NULL;
7192+ int offset;
7193+
7194+ if ((offset = hid_find_field(hid, type, code, &field)) == -1) {
7195+ warn("event field not found");
7196+ return -1;
7197+ }
7198
7199- hid_set_field(field, offset, value);
7200- hid_write_report(hid, field->report);
7201+ hid_set_field(field, offset, value);
7202+ hid_submit_report(hid, field->report, USB_DIR_OUT);
7203+ }
7204
7205 return 0;
7206 }
7207@@ -361,12 +406,22 @@
7208 static int hidinput_open(struct input_dev *dev)
7209 {
7210 struct hid_device *hid = dev->private;
7211+/*
7212+#ifdef CONFIG_HID_FF
7213+ hid_ff_open(hid);
7214+#endif
7215+*/
7216 return hid_open(hid);
7217 }
7218
7219 static void hidinput_close(struct input_dev *dev)
7220 {
7221 struct hid_device *hid = dev->private;
7222+/*
7223+#ifdef CONFIG_HID_FF
7224+ hid_ff_close(hid);
7225+#endif
7226+*/
7227 hid_close(hid);
7228 }
7229
7230@@ -395,8 +450,9 @@
7231 hid->input.event = hidinput_input_event;
7232 hid->input.open = hidinput_open;
7233 hid->input.close = hidinput_close;
7234-
7235 hid->input.name = hid->name;
7236+ hid->input.phys = hid->phys;
7237+ hid->input.uniq = hid->uniq;
7238 hid->input.idbus = BUS_USB;
7239 hid->input.idvendor = dev->descriptor.idVendor;
7240 hid->input.idproduct = dev->descriptor.idProduct;
7241diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hid-lgff.c linux-modified/drivers/usb/hid-lgff.c
7242--- linux-vanilla/drivers/usb/hid-lgff.c Thu Jan 1 02:00:00 1970
7243+++ linux-modified/drivers/usb/hid-lgff.c Sun Mar 9 18:03:20 2003
7244@@ -0,0 +1,588 @@
7245+/*
7246+ * Force feedback support for hid-compliant for some of the devices from
7247+ * Logitech, namely:
7248+ * - WingMan Cordless RumblePad
7249+ * - WingMan Force 3D
7250+ * - WingMan Strike Force 3D
7251+ * Other possibly supported devices:
7252+ * Apparently *not* supported:
7253+ * - WingMan Formula Force GP
7254+ * - WingMan RumblePad (ie the non-cordless one)
7255+ *
7256+ * Copyright (c) 2002 Johann Deneux
7257+ */
7258+
7259+/*
7260+ * This program is free software; you can redistribute it and/or modify
7261+ * it under the terms of the GNU General Public License as published by
7262+ * the Free Software Foundation; either version 2 of the License, or
7263+ * (at your option) any later version.
7264+ *
7265+ * This program is distributed in the hope that it will be useful,
7266+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7267+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7268+ * GNU General Public License for more details.
7269+ *
7270+ * You should have received a copy of the GNU General Public License
7271+ * along with this program; if not, write to the Free Software
7272+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7273+ *
7274+ * Should you need to contact me, the author, you can do so by
7275+ * e-mail - mail your message to <deneux@ifrance.com>
7276+ */
7277+
7278+/* TODO:
7279+ Support periodic, custom and condition effects.
7280+ Support gain setting + default spring.
7281+*/
7282+
7283+#include <linux/input.h>
7284+#include <linux/sched.h>
7285+
7286+#define DEBUG
7287+#include <linux/usb.h>
7288+
7289+#include <linux/circ_buf.h>
7290+
7291+#include "hid.h"
7292+#include "fixp-arith.h"
7293+
7294+
7295+/* Periodicity of the update */
7296+#define PERIOD (HZ/10)
7297+
7298+#define RUN_AT(t) (jiffies + (t))
7299+
7300+/* Effect status */
7301+#define EFFECT_STARTED 0 /* Effect is going to play after some time
7302+ (ff_replay.delay) */
7303+#define EFFECT_PLAYING 1 /* Effect is being played */
7304+#define EFFECT_USED 2
7305+
7306+// For lgff_device::flags
7307+#define DEVICE_CLOSING 0 /* The driver is being unitialised */
7308+
7309+#define LGFF_EFFECTS 8
7310+
7311+struct device_type {
7312+ u16 idVendor;
7313+ u16 idProduct;
7314+ signed short *ff;
7315+};
7316+
7317+struct lgff_effect {
7318+ pid_t owner;
7319+
7320+ struct ff_effect effect;
7321+
7322+ unsigned long flags[1];
7323+ unsigned int count; /* Number of times left to play */
7324+ unsigned long started_at; /* When the effect started to play */
7325+};
7326+
7327+struct lgff_device {
7328+ struct hid_device* hid;
7329+
7330+ struct hid_report* constant;
7331+ struct hid_report* rumble;
7332+ struct hid_report* condition;
7333+
7334+ struct lgff_effect effects[LGFF_EFFECTS];
7335+ spinlock_t lock; /* device-level lock. Having locks on
7336+ a per-effect basis could be nice, but
7337+ isn't really necessary */
7338+
7339+ unsigned long flags[1]; /* Contains various information about the
7340+ state of the driver for this device */
7341+
7342+ struct timer_list timer;
7343+};
7344+
7345+/* Callbacks */
7346+static void hid_lgff_exit(struct hid_device* hid);
7347+static int hid_lgff_event(struct hid_device *hid, struct input_dev *input,
7348+ unsigned int type, unsigned int code, int value);
7349+static int hid_lgff_flush(struct input_dev *input, struct file *file);
7350+static int hid_lgff_upload_effect(struct input_dev *input,
7351+ struct ff_effect *effect);
7352+static int hid_lgff_erase(struct input_dev *input, int id);
7353+
7354+/* Local functions */
7355+static void hid_lgff_input_init(struct hid_device* hid);
7356+static void hid_lgff_timer(unsigned long timer_data);
7357+static struct hid_report* hid_lgff_duplicate_report(struct hid_report*);
7358+static void hid_lgff_delete_report(struct hid_report*);
7359+
7360+static signed short ff_rumble[] = {
7361+ FF_RUMBLE,
7362+ -1
7363+};
7364+
7365+static signed short ff_joystick[] = {
7366+ FF_CONSTANT,
7367+ ABS_X,
7368+ ABS_Y,
7369+ -1
7370+};
7371+
7372+static struct device_type devices[] = {
7373+ {0x046d, 0xc211, ff_rumble},
7374+ {0x046d, 0xc283, ff_joystick},
7375+ {0x046d, 0xc285, ff_joystick},
7376+ {0x0000, 0x0000, ff_joystick}
7377+};
7378+
7379+int hid_lgff_init(struct hid_device* hid)
7380+{
7381+ struct lgff_device *private;
7382+ struct hid_report* report;
7383+ struct hid_field* field;
7384+
7385+ switch (hid->dev->descriptor.idVendor) {
7386+ case 0x46d: // Logitech
7387+ switch (hid->dev->descriptor.idProduct) {
7388+ /* Supported devices */
7389+ case 0xc211: // Cordless rumblepad
7390+ case 0xc283: // Force 3D
7391+ case 0xc285: // Strike Force 3D
7392+ break;
7393+ /* Unsupported or unknown devices */
7394+ default: return 1;
7395+ }
7396+ break;
7397+
7398+ case 0x6a3: // Saitek
7399+ switch (hid->dev->descriptor.idProduct) {
7400+ case 0xff12: // Cyborg 3D Force
7401+ break;
7402+ default: return 1;
7403+ }
7404+ break;
7405+
7406+ default: return 1;
7407+ }
7408+
7409+ /* Find the report to use */
7410+ if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
7411+ err("No output report found");
7412+ return -1;
7413+ }
7414+ /* Check that the report looks ok */
7415+ report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
7416+ if (!report) {
7417+ err("NULL output report");
7418+ return -1;
7419+ }
7420+ field = report->field[0];
7421+ if (!field) {
7422+ err("NULL field");
7423+ return -1;
7424+ }
7425+
7426+ private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
7427+ if (!private) return -1;
7428+ memset(private, 0, sizeof(struct lgff_device));
7429+ hid->ff_private = private;
7430+
7431+ /* Input init */
7432+ hid_lgff_input_init(hid);
7433+
7434+
7435+ private->constant = hid_lgff_duplicate_report(report);
7436+ if (!private->constant) {
7437+ kfree(private);
7438+ return -1;
7439+ }
7440+ private->constant->field[0]->value[0] = 0x51;
7441+ private->constant->field[0]->value[1] = 0x08;
7442+ private->constant->field[0]->value[2] = 0x7f;
7443+ private->constant->field[0]->value[3] = 0x7f;
7444+
7445+ private->rumble = hid_lgff_duplicate_report(report);
7446+ if (!private->rumble) {
7447+ hid_lgff_delete_report(private->constant);
7448+ kfree(private);
7449+ return -1;
7450+ }
7451+ private->rumble->field[0]->value[0] = 0x03;
7452+ private->rumble->field[0]->value[1] = 0x42;
7453+
7454+
7455+ private->condition = hid_lgff_duplicate_report(report);
7456+ if (!private->condition) {
7457+ hid_lgff_delete_report(private->rumble);
7458+ hid_lgff_delete_report(private->constant);
7459+ kfree(private);
7460+ return -1;
7461+ }
7462+
7463+ private->hid = hid;
7464+
7465+ spin_lock_init(&private->lock);
7466+ init_timer(&private->timer);
7467+ private->timer.data = (unsigned long)private;
7468+ private->timer.function = hid_lgff_timer;
7469+
7470+ /* Event and exit callbacks */
7471+ hid->ff_exit = hid_lgff_exit;
7472+ hid->ff_event = hid_lgff_event;
7473+
7474+ /* Start the update task */
7475+ private->timer.expires = RUN_AT(PERIOD);
7476+ add_timer(&private->timer); /*TODO: only run the timer when at least
7477+ one effect is playing */
7478+
7479+ printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <deneux@ifrance.com>\n");
7480+
7481+ return 0;
7482+}
7483+
7484+static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
7485+{
7486+ struct hid_report* ret;
7487+
7488+ ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
7489+ if (!ret) return NULL;
7490+ *ret = *report;
7491+
7492+ ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
7493+ if (!ret->field[0]) {
7494+ kfree(ret);
7495+ return NULL;
7496+ }
7497+ *ret->field[0] = *report->field[0];
7498+
7499+ ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL);
7500+ if (!ret->field[0]->value) {
7501+ kfree(ret->field[0]);
7502+ kfree(ret);
7503+ return NULL;
7504+ }
7505+ memset(ret->field[0]->value, 0, sizeof(s32[8]));
7506+
7507+ return ret;
7508+}
7509+
7510+static void hid_lgff_delete_report(struct hid_report* report)
7511+{
7512+ if (report) {
7513+ kfree(report->field[0]->value);
7514+ kfree(report->field[0]);
7515+ kfree(report);
7516+ }
7517+}
7518+
7519+static void hid_lgff_input_init(struct hid_device* hid)
7520+{
7521+ struct device_type* dev = devices;
7522+ signed short* ff;
7523+ u16 idVendor = hid->dev->descriptor.idVendor;
7524+ u16 idProduct = hid->dev->descriptor.idProduct;
7525+
7526+ while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
7527+ dev++;
7528+
7529+ ff = dev->ff;
7530+
7531+ while (*ff >= 0) {
7532+ set_bit(*ff, hid->input.ffbit);
7533+ ++ff;
7534+ }
7535+
7536+ hid->input.upload_effect = hid_lgff_upload_effect;
7537+ hid->input.flush = hid_lgff_flush;
7538+
7539+ set_bit(EV_FF, hid->input.evbit);
7540+ hid->input.ff_effects_max = LGFF_EFFECTS;
7541+}
7542+
7543+static void hid_lgff_exit(struct hid_device* hid)
7544+{
7545+ struct lgff_device *lgff = hid->ff_private;
7546+
7547+ set_bit(DEVICE_CLOSING, lgff->flags);
7548+ del_timer_sync(&lgff->timer);
7549+
7550+ hid_lgff_delete_report(lgff->condition);
7551+ hid_lgff_delete_report(lgff->rumble);
7552+ hid_lgff_delete_report(lgff->constant);
7553+
7554+ kfree(lgff);
7555+}
7556+
7557+static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
7558+ unsigned int type, unsigned int code, int value)
7559+{
7560+ struct lgff_device *lgff = hid->ff_private;
7561+ struct lgff_effect *effect = lgff->effects + code;
7562+ unsigned long flags;
7563+
7564+ if (type != EV_FF) return -EINVAL;
7565+ if (value < 0) return -EINVAL;
7566+
7567+ spin_lock_irqsave(&lgff->lock, flags);
7568+
7569+ if (value > 0) {
7570+ if (test_bit(EFFECT_STARTED, effect->flags)) {
7571+ spin_unlock_irqrestore(&lgff->lock, flags);
7572+ return -EBUSY;
7573+ }
7574+ if (test_bit(EFFECT_PLAYING, effect->flags)) {
7575+ spin_unlock_irqrestore(&lgff->lock, flags);
7576+ return -EBUSY;
7577+ }
7578+
7579+ effect->count = value;
7580+
7581+ if (effect->effect.replay.delay) {
7582+ set_bit(EFFECT_STARTED, effect->flags);
7583+ } else {
7584+ set_bit(EFFECT_PLAYING, effect->flags);
7585+ }
7586+ effect->started_at = jiffies;
7587+ }
7588+ else { /* value == 0 */
7589+ clear_bit(EFFECT_STARTED, effect->flags);
7590+ clear_bit(EFFECT_PLAYING, effect->flags);
7591+ }
7592+
7593+ spin_unlock_irqrestore(&lgff->lock, flags);
7594+
7595+ return 0;
7596+
7597+}
7598+
7599+/* Erase all effects this process owns */
7600+static int hid_lgff_flush(struct input_dev *dev, struct file *file)
7601+{
7602+ struct hid_device *hid = dev->private;
7603+ struct lgff_device *lgff = hid->ff_private;
7604+ int i;
7605+
7606+ for (i=0; i<dev->ff_effects_max; ++i) {
7607+
7608+ /*NOTE: no need to lock here. The only times EFFECT_USED is
7609+ modified is when effects are uploaded or when an effect is
7610+ erased. But a process cannot close its dev/input/eventX fd
7611+ and perform ioctls on the same fd all at the same time */
7612+ if ( current->pid == lgff->effects[i].owner
7613+ && test_bit(EFFECT_USED, lgff->effects[i].flags)) {
7614+
7615+ if (hid_lgff_erase(dev, i))
7616+ warn("erase effect %d failed", i);
7617+ }
7618+
7619+ }
7620+
7621+ return 0;
7622+}
7623+
7624+static int hid_lgff_erase(struct input_dev *dev, int id)
7625+{
7626+ struct hid_device *hid = dev->private;
7627+ struct lgff_device *lgff = hid->ff_private;
7628+ unsigned long flags;
7629+
7630+ spin_lock_irqsave(&lgff->lock, flags);
7631+ lgff->effects[id].flags[0] = 0;
7632+ spin_unlock_irqrestore(&lgff->lock, flags);
7633+
7634+ return 0;
7635+}
7636+
7637+static int hid_lgff_upload_effect(struct input_dev* input,
7638+ struct ff_effect* effect)
7639+{
7640+ struct hid_device *hid = input->private;
7641+ struct lgff_device *lgff = hid->ff_private;
7642+ struct lgff_effect new;
7643+ int id;
7644+ unsigned long flags;
7645+
7646+ dbg("ioctl rumble");
7647+
7648+ if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
7649+
7650+ spin_lock_irqsave(&lgff->lock, flags);
7651+
7652+ if (effect->id == -1) {
7653+ int i;
7654+
7655+ for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i);
7656+ if (i >= LGFF_EFFECTS) {
7657+ spin_unlock_irqrestore(&lgff->lock, flags);
7658+ return -ENOSPC;
7659+ }
7660+
7661+ effect->id = i;
7662+ lgff->effects[i].owner = current->pid;
7663+ lgff->effects[i].flags[0] = 0;
7664+ set_bit(EFFECT_USED, lgff->effects[i].flags);
7665+ }
7666+
7667+ id = effect->id;
7668+ new = lgff->effects[id];
7669+
7670+ new.effect = *effect;
7671+
7672+ if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
7673+ || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {
7674+
7675+ /* Changing replay parameters is not allowed (for the time
7676+ being) */
7677+ if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay
7678+ || new.effect.replay.length != lgff->effects[id].effect.replay.length) {
7679+ spin_unlock_irqrestore(&lgff->lock, flags);
7680+ return -ENOSYS;
7681+ }
7682+
7683+ lgff->effects[id] = new;
7684+
7685+ } else {
7686+ lgff->effects[id] = new;
7687+ }
7688+
7689+ spin_unlock_irqrestore(&lgff->lock, flags);
7690+ return 0;
7691+}
7692+
7693+static void hid_lgff_compute_constant(struct lgff_effect *effect,
7694+ int *x, int *y)
7695+{
7696+ int level;
7697+ unsigned long now = jiffies;
7698+ int degrees;
7699+
7700+ // During attack ?
7701+ if (effect->effect.u.constant.envelope.attack_length &&
7702+ !time_after(now,
7703+ effect->started_at
7704+ + (effect->effect.u.constant.envelope.attack_length + effect->effect.replay.delay)*HZ/1000)) {
7705+ level = effect->effect.u.constant.level
7706+ - effect->effect.u.constant.envelope.attack_level;
7707+ //TODO compute incrementally, to save mults and divs
7708+ level *= now - effect->started_at - effect->effect.replay.delay;
7709+ level /= effect->effect.u.constant.envelope.attack_length;
7710+// dbg("During attack");
7711+ }
7712+ // During fade ?
7713+ else if (effect->effect.replay.length &&
7714+ effect->effect.u.constant.envelope.fade_length &&
7715+ time_after(now,
7716+ effect->started_at
7717+ + (effect->effect.replay.delay + effect->effect.replay.length) * HZ/1000)) {
7718+ level = effect->effect.u.constant.envelope.fade_level
7719+ - effect->effect.u.constant.level;
7720+ //TODO compute incrementally, to save mults and divs
7721+ level *= now - (effect->started_at + effect->effect.replay.delay + effect->effect.replay.length - effect->effect.u.constant.envelope.fade_length) ;
7722+ level /= effect->effect.u.constant.envelope.fade_length;
7723+// dbg("During fade");
7724+ }
7725+ else {
7726+ level = effect->effect.u.constant.level;
7727+// dbg("During middle");
7728+ }
7729+// dbg("level = %d", level);
7730+
7731+ degrees = effect->effect.direction * 360 >> 16;
7732+ *x += fixp_mult(fixp_sin(degrees),
7733+ level);
7734+ *y += fixp_mult(-fixp_cos(degrees),
7735+ level);
7736+}
7737+
7738+static void hid_lgff_timer(unsigned long timer_data)
7739+{
7740+ struct lgff_device *lgff = (struct lgff_device*)timer_data;
7741+ struct hid_device *hid = lgff->hid;
7742+ unsigned long flags;
7743+ int x=0x7fff, y=0x7fff; // Coordinates of constant effects
7744+ unsigned int left = 0, right = 0; // Rumbling
7745+ int i;
7746+
7747+ spin_lock_irqsave(&lgff->lock, flags);
7748+
7749+ for (i=0; i<LGFF_EFFECTS; ++i) {
7750+ struct lgff_effect* effect = lgff->effects +i;
7751+
7752+ if (test_bit(EFFECT_PLAYING, effect->flags)) {
7753+
7754+ switch (effect->effect.type) {
7755+ case FF_CONSTANT:
7756+ hid_lgff_compute_constant(effect, &x, &y);
7757+ break;
7758+ case FF_RUMBLE:
7759+ right += effect->effect.u.rumble.strong_magnitude;
7760+ left += effect->effect.u.rumble.weak_magnitude;
7761+ break;
7762+ };
7763+
7764+ /* One run of the effect is finished playing */
7765+ if (effect->effect.replay.length &&
7766+ time_after(jiffies,
7767+ effect->started_at
7768+ + effect->effect.replay.delay*HZ/1000
7769+ + effect->effect.replay.length*HZ/1000)) {
7770+ dbg("Finished playing once %d", i);
7771+ if (--effect->count <= 0) {
7772+ dbg("Stopped %d", i);
7773+ clear_bit(EFFECT_PLAYING, effect->flags);
7774+ }
7775+ else {
7776+ dbg("Start again %d", i);
7777+ if (effect->effect.replay.length != 0) {
7778+ clear_bit(EFFECT_PLAYING, effect->flags);
7779+ set_bit(EFFECT_STARTED, effect->flags);
7780+ }
7781+ effect->started_at = jiffies;
7782+ }
7783+ }
7784+
7785+ } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) {
7786+ /* Check if we should start playing the effect */
7787+ if (time_after(jiffies,
7788+ lgff->effects[i].started_at
7789+ + lgff->effects[i].effect.replay.delay*HZ/1000)) {
7790+ dbg("Now playing %d", i);
7791+ clear_bit(EFFECT_STARTED, lgff->effects[i].flags);
7792+ set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
7793+ }
7794+ }
7795+ }
7796+
7797+ x >>= 8;
7798+ y >>= 8;
7799+
7800+#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
7801+
7802+ // Clamp values
7803+ CLAMP(x);
7804+ CLAMP(y);
7805+ CLAMP(left);
7806+ CLAMP(right);
7807+
7808+#undef CLAMP
7809+
7810+ if (x != lgff->constant->field[0]->value[2]
7811+ || y != lgff->constant->field[0]->value[3]) {
7812+ lgff->constant->field[0]->value[2] = x;
7813+ lgff->constant->field[0]->value[3] = y;
7814+ dbg("(x,y)=(%04x, %04x)", x, y);
7815+ hid_submit_report(hid, lgff->constant, USB_DIR_OUT);
7816+ }
7817+
7818+ if (left != lgff->rumble->field[0]->value[3]
7819+ || right != lgff->rumble->field[0]->value[4]) {
7820+ lgff->rumble->field[0]->value[3] = left;
7821+ lgff->rumble->field[0]->value[4] = right;
7822+ dbg("(left,right)=(%04x, %04x)", left, right);
7823+ hid_submit_report(hid, lgff->rumble, USB_DIR_OUT);
7824+ }
7825+
7826+ if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
7827+ lgff->timer.expires = RUN_AT(PERIOD);
7828+ add_timer(&lgff->timer);
7829+ }
7830+
7831+ spin_unlock_irqrestore(&lgff->lock, flags);
7832+}
7833diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hid.h linux-modified/drivers/usb/hid.h
7834--- linux-vanilla/drivers/usb/hid.h Fri Nov 29 01:53:14 2002
7835+++ linux-modified/drivers/usb/hid.h Sun Mar 9 17:01:16 2003
7836@@ -2,12 +2,10 @@
7837 #define __HID_H
7838
7839 /*
7840- * $Id$
7841+ * $Id$
7842 *
7843 * Copyright (c) 1999 Andreas Gal
7844 * Copyright (c) 2000-2001 Vojtech Pavlik
7845- *
7846- * Sponsored by SuSE
7847 */
7848
7849 /*
7850@@ -26,8 +24,8 @@
7851 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7852 *
7853 * Should you need to contact me, the author, you can do so either by
7854- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
7855- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
7856+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
7857+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
7858 */
7859
7860 #include <linux/types.h>
7861@@ -41,6 +39,25 @@
7862 #define USB_INTERFACE_CLASS_HID 3
7863
7864 /*
7865+ * HID class requests
7866+ */
7867+
7868+#define HID_REQ_GET_REPORT 0x01
7869+#define HID_REQ_GET_IDLE 0x02
7870+#define HID_REQ_GET_PROTOCOL 0x03
7871+#define HID_REQ_SET_REPORT 0x09
7872+#define HID_REQ_SET_IDLE 0x0A
7873+#define HID_REQ_SET_PROTOCOL 0x0B
7874+
7875+/*
7876+ * HID class descriptor types
7877+ */
7878+
7879+#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
7880+#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
7881+#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
7882+
7883+/*
7884 * We parse each description item into this structure. Short items data
7885 * values are expanded to 32-bit signed int, long items contain a pointer
7886 * into the data area.
7887@@ -158,9 +175,11 @@
7888 #define HID_UP_KEYBOARD 0x00070000
7889 #define HID_UP_LED 0x00080000
7890 #define HID_UP_BUTTON 0x00090000
7891+#define HID_UP_ORDINAL 0x000a0000
7892 #define HID_UP_CONSUMER 0x000c0000
7893 #define HID_UP_DIGITIZER 0x000d0000
7894 #define HID_UP_PID 0x000f0000
7895+#define HID_UP_HPVENDOR 0xff7f0000
7896
7897 #define HID_USAGE 0x0000ffff
7898
7899@@ -199,7 +218,7 @@
7900 __s32 logical_maximum;
7901 __s32 physical_minimum;
7902 __s32 physical_maximum;
7903- unsigned unit_exponent;
7904+ __s32 unit_exponent;
7905 unsigned unit;
7906 unsigned report_id;
7907 unsigned report_size;
7908@@ -256,9 +275,10 @@
7909 __s32 logical_maximum;
7910 __s32 physical_minimum;
7911 __s32 physical_maximum;
7912- unsigned unit_exponent;
7913+ __s32 unit_exponent;
7914 unsigned unit;
7915 struct hid_report *report; /* associated report */
7916+ unsigned index; /* index into report->field[] */
7917 };
7918
7919 #define HID_MAX_FIELDS 64
7920@@ -270,8 +290,6 @@
7921 struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
7922 unsigned maxfield; /* maximum valid field index */
7923 unsigned size; /* size of the report (bits) */
7924- unsigned idx; /* where we're in data */
7925- unsigned char *data; /* data for multi-packet reports */
7926 struct hid_device *device; /* associated device */
7927 };
7928
7929@@ -284,16 +302,20 @@
7930 #define HID_REPORT_TYPES 3
7931
7932 #define HID_BUFFER_SIZE 32
7933-#define HID_CONTROL_FIFO_SIZE 8
7934+#define HID_CONTROL_FIFO_SIZE 64
7935+#define HID_OUTPUT_FIFO_SIZE 64
7936
7937 struct hid_control_fifo {
7938- struct usb_ctrlrequest dr;
7939- char buffer[HID_BUFFER_SIZE];
7940+ unsigned char dir;
7941+ struct hid_report *report;
7942 };
7943
7944 #define HID_CLAIMED_INPUT 1
7945 #define HID_CLAIMED_HIDDEV 2
7946
7947+#define HID_CTRL_RUNNING 1
7948+#define HID_OUT_RUNNING 2
7949+
7950 struct hid_device { /* device report descriptor */
7951 __u8 *rdesc;
7952 unsigned rsize;
7953@@ -306,12 +328,23 @@
7954 struct usb_device *dev; /* USB device */
7955 int ifnum; /* USB interface number */
7956
7957- struct urb urb; /* USB URB structure */
7958- char buffer[HID_BUFFER_SIZE]; /* Rx buffer */
7959+ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
7960
7961- struct urb urbout; /* Output URB */
7962- struct hid_control_fifo out[HID_CONTROL_FIFO_SIZE]; /* Transmit buffer */
7963- unsigned char outhead, outtail; /* Tx buffer head & tail */
7964+ struct urb *urbin; /* Input URB */
7965+ char inbuf[HID_BUFFER_SIZE]; /* Input buffer */
7966+
7967+ struct urb *urbctrl; /* Control URB */
7968+ struct usb_ctrlrequest dr; /* Control request struct */
7969+ struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
7970+ unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
7971+ char ctrlbuf[HID_BUFFER_SIZE]; /* Control buffer */
7972+ spinlock_t ctrllock; /* Control fifo spinlock */
7973+
7974+ struct urb *urbout; /* Output URB */
7975+ struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
7976+ unsigned char outhead, outtail; /* Output pipe fifo head & tail */
7977+ char outbuf[HID_BUFFER_SIZE]; /* Output buffer */
7978+ spinlock_t outlock; /* Output fifo spinlock */
7979
7980 unsigned claimed; /* Claimed by hidinput, hiddev? */
7981 unsigned quirks; /* Various quirks the device can pull on us */
7982@@ -320,8 +353,17 @@
7983 void *hiddev; /* The hiddev structure */
7984 int minor; /* Hiddev minor number */
7985
7986+ wait_queue_head_t wait; /* For sleeping */
7987+
7988 int open; /* is the device open by anyone? */
7989 char name[128]; /* Device name */
7990+ char phys[64]; /* Device physical location */
7991+ char uniq[64]; /* Device unique identifier (serial #) */
7992+
7993+ void *ff_private; /* Private data for the force-feedback driver */
7994+ void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */
7995+ int (*ff_event)(struct hid_device *hid, struct input_dev *input,
7996+ unsigned int type, unsigned int code, int value);
7997 };
7998
7999 #define HID_GLOBAL_STACK_SIZE 4
8000@@ -352,32 +394,44 @@
8001 struct hid_class_descriptor desc[1];
8002 } __attribute__ ((packed));
8003
8004+void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
8005+int hidinput_connect(struct hid_device *);
8006+void hidinput_disconnect(struct hid_device *);
8007
8008 #ifdef DEBUG
8009 #include "hid-debug.h"
8010 #else
8011 #define hid_dump_input(a,b) do { } while (0)
8012 #define hid_dump_device(c) do { } while (0)
8013+#define hid_dump_field(a,b) do { } while (0)
8014 #endif
8015
8016 #endif
8017
8018-#ifdef CONFIG_USB_HIDINPUT
8019-#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001))
8020-extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
8021-extern int hidinput_connect(struct hid_device *);
8022-extern void hidinput_disconnect(struct hid_device *);
8023-#else
8024-#define IS_INPUT_APPLICATION(a) (0)
8025-static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
8026-static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
8027-static inline void hidinput_disconnect(struct hid_device *hid) { }
8028-#endif
8029+/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
8030+/* We ignore a few input applications that are not widely used */
8031+#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001))
8032
8033 int hid_open(struct hid_device *);
8034 void hid_close(struct hid_device *);
8035 int hid_find_field(struct hid_device *, unsigned int, unsigned int, struct hid_field **);
8036 int hid_set_field(struct hid_field *, unsigned, __s32);
8037-void hid_write_report(struct hid_device *, struct hid_report *);
8038-void hid_read_report(struct hid_device *, struct hid_report *);
8039+void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
8040 void hid_init_reports(struct hid_device *hid);
8041+
8042+
8043+#ifdef CONFIG_HID_FF
8044+
8045+int hid_ff_init(struct hid_device *hid);
8046+static inline void hid_ff_exit(struct hid_device *hid)
8047+{
8048+ if (hid->ff_exit) hid->ff_exit(hid);
8049+}
8050+
8051+static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input,
8052+ unsigned int type, unsigned int code, int value)
8053+{
8054+ if (hid->ff_event) return hid->ff_event(hid, input, type, code, value);
8055+ return -ENOSYS;
8056+}
8057+#endif
8058diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/hiddev.c linux-modified/drivers/usb/hiddev.c
8059--- linux-vanilla/drivers/usb/hiddev.c Sun Oct 21 04:13:11 2001
8060+++ linux-modified/drivers/usb/hiddev.c Mon Jan 6 16:48:21 2003
8061@@ -50,9 +50,10 @@
8062 };
8063
8064 struct hiddev_list {
8065- struct hiddev_event buffer[HIDDEV_BUFFER_SIZE];
8066+ struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
8067 int head;
8068 int tail;
8069+ unsigned flags;
8070 struct fasync_struct *fasync;
8071 struct hiddev *hiddev;
8072 struct hiddev_list *next;
8073@@ -146,17 +147,19 @@
8074 * This is where hid.c calls into hiddev to pass an event that occurred over
8075 * the interrupt pipe
8076 */
8077-void hiddev_hid_event(struct hid_device *hid, unsigned int usage, int value)
8078+void hiddev_hid_event(struct hid_device *hid, struct hiddev_usage_ref *uref)
8079 {
8080 struct hiddev *hiddev = hid->hiddev;
8081 struct hiddev_list *list = hiddev->list;
8082
8083 while (list) {
8084- list->buffer[list->head].hid = usage;
8085- list->buffer[list->head].value = value;
8086- list->head = (list->head + 1) & (HIDDEV_BUFFER_SIZE - 1);
8087-
8088- kill_fasync(&list->fasync, SIGIO, POLL_IN);
8089+ if (uref->field_index != HID_FIELD_INDEX_NONE ||
8090+ (list->flags & HIDDEV_FLAG_REPORT) != 0) {
8091+ list->buffer[list->head] = *uref;
8092+ list->head = (list->head + 1) &
8093+ (HIDDEV_BUFFER_SIZE - 1);
8094+ kill_fasync(&list->fasync, SIGIO, POLL_IN);
8095+ }
8096
8097 list = list->next;
8098 }
8099@@ -193,7 +196,6 @@
8100 struct hiddev_list *list = file->private_data;
8101 struct hiddev_list **listptr;
8102
8103- lock_kernel();
8104 listptr = &list->hiddev->list;
8105 hiddev_fasync(-1, file, 0);
8106
8107@@ -209,7 +211,6 @@
8108 }
8109
8110 kfree(list);
8111- unlock_kernel();
8112
8113 return 0;
8114 }
8115@@ -220,7 +221,7 @@
8116 static int hiddev_open(struct inode * inode, struct file * file) {
8117 struct hiddev_list *list;
8118
8119- int i = MINOR(inode->i_rdev) - HIDDEV_MINOR_BASE;
8120+ int i = minor(inode->i_rdev) - HIDDEV_MINOR_BASE;
8121
8122 if (i >= HIDDEV_MINORS || !hiddev_table[i])
8123 return -ENODEV;
8124@@ -259,43 +260,67 @@
8125 {
8126 DECLARE_WAITQUEUE(wait, current);
8127 struct hiddev_list *list = file->private_data;
8128+ int event_size;
8129 int retval = 0;
8130
8131- if (list->head == list->tail) {
8132-
8133- add_wait_queue(&list->hiddev->wait, &wait);
8134- set_current_state(TASK_INTERRUPTIBLE);
8135+ event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
8136+ sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
8137
8138- while (list->head == list->tail) {
8139+ if (count < event_size) return 0;
8140
8141- if (file->f_flags & O_NONBLOCK) {
8142- retval = -EAGAIN;
8143- break;
8144- }
8145- if (signal_pending(current)) {
8146- retval = -ERESTARTSYS;
8147- break;
8148- }
8149- if (!list->hiddev->exist) {
8150- retval = -EIO;
8151- break;
8152+ while (retval == 0) {
8153+ if (list->head == list->tail) {
8154+ add_wait_queue(&list->hiddev->wait, &wait);
8155+ set_current_state(TASK_INTERRUPTIBLE);
8156+
8157+ while (list->head == list->tail) {
8158+ if (file->f_flags & O_NONBLOCK) {
8159+ retval = -EAGAIN;
8160+ break;
8161+ }
8162+ if (signal_pending(current)) {
8163+ retval = -ERESTARTSYS;
8164+ break;
8165+ }
8166+ if (!list->hiddev->exist) {
8167+ retval = -EIO;
8168+ break;
8169+ }
8170+
8171+ schedule();
8172 }
8173
8174- schedule();
8175+ set_current_state(TASK_RUNNING);
8176+ remove_wait_queue(&list->hiddev->wait, &wait);
8177 }
8178
8179- set_current_state(TASK_RUNNING);
8180- remove_wait_queue(&list->hiddev->wait, &wait);
8181- }
8182+ if (retval)
8183+ return retval;
8184
8185- if (retval)
8186- return retval;
8187
8188- while (list->head != list->tail && retval + sizeof(struct hiddev_event) <= count) {
8189- if (copy_to_user(buffer + retval, list->buffer + list->tail,
8190- sizeof(struct hiddev_event))) return -EFAULT;
8191- list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
8192- retval += sizeof(struct hiddev_event);
8193+ while (list->head != list->tail &&
8194+ retval + event_size <= count) {
8195+ if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
8196+ if (list->buffer[list->tail].field_index !=
8197+ HID_FIELD_INDEX_NONE) {
8198+ struct hiddev_event event;
8199+ event.hid = list->buffer[list->tail].usage_code;
8200+ event.value = list->buffer[list->tail].value;
8201+ if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event)))
8202+ return -EFAULT;
8203+ retval += sizeof(struct hiddev_event);
8204+ }
8205+ } else {
8206+ if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
8207+ (list->flags & HIDDEV_FLAG_REPORT) != 0) {
8208+ if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref)))
8209+ return -EFAULT;
8210+ retval += sizeof(struct hiddev_usage_ref);
8211+ }
8212+ }
8213+ list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
8214+ }
8215+
8216 }
8217
8218 return retval;
8219@@ -360,6 +385,25 @@
8220 return copy_to_user((void *) arg, &dinfo, sizeof(dinfo));
8221 }
8222
8223+ case HIDIOCGFLAG:
8224+ return put_user(list->flags, (int *) arg);
8225+
8226+ case HIDIOCSFLAG:
8227+ {
8228+ int newflags;
8229+ if (get_user(newflags, (int *) arg))
8230+ return -EFAULT;
8231+
8232+ if ((newflags & ~HIDDEV_FLAGS) != 0 ||
8233+ ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
8234+ (newflags & HIDDEV_FLAG_UREF) == 0))
8235+ return -EINVAL;
8236+
8237+ list->flags = newflags;
8238+
8239+ return 0;
8240+ }
8241+
8242 case HIDIOCGSTRING:
8243 {
8244 int idx, len;
8245@@ -402,7 +446,7 @@
8246 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
8247 return -EINVAL;
8248
8249- hid_read_report(hid, report);
8250+ hid_submit_report(hid, report, USB_DIR_IN);
8251
8252 return 0;
8253
8254@@ -416,7 +460,7 @@
8255 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
8256 return -EINVAL;
8257
8258- hid_write_report(hid, report);
8259+ hid_submit_report(hid, report, USB_DIR_OUT);
8260
8261 return 0;
8262
8263diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/usb-ohci.c linux-modified/drivers/usb/usb-ohci.c
8264--- linux-vanilla/drivers/usb/usb-ohci.c Fri Nov 29 01:53:15 2002
8265+++ linux-modified/drivers/usb/usb-ohci.c Mon Jan 6 16:48:21 2003
8266@@ -74,7 +74,7 @@
8267 #include <asm/unaligned.h>
8268
8269 #define OHCI_USE_NPS // force NoPowerSwitching mode
8270-// #define OHCI_VERBOSE_DEBUG /* not always helpful */
8271+#undef OHCI_VERBOSE_DEBUG /* not always helpful */
8272
8273 #include "usb-ohci.h"
8274
8275diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/usbkbd.c linux-modified/drivers/usb/usbkbd.c
8276--- linux-vanilla/drivers/usb/usbkbd.c Fri Nov 29 01:53:15 2002
8277+++ linux-modified/drivers/usb/usbkbd.c Mon Jan 6 16:48:21 2003
8278@@ -250,8 +250,8 @@
8279
8280 input_register_device(&kbd->dev);
8281
8282- printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
8283- kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum);
8284+ printk(KERN_INFO "input: %s on usb%d:%d.%d\n",
8285+ kbd->name, dev->bus->busnum, dev->devnum, ifnum);
8286
8287 return kbd;
8288 }
8289diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/usbmouse.c linux-modified/drivers/usb/usbmouse.c
8290--- linux-vanilla/drivers/usb/usbmouse.c Sat Aug 3 02:39:45 2002
8291+++ linux-modified/drivers/usb/usbmouse.c Mon Jan 6 16:48:21 2003
8292@@ -166,8 +166,8 @@
8293
8294 input_register_device(&mouse->dev);
8295
8296- printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
8297- mouse->dev.number, mouse->name, dev->bus->busnum, dev->devnum, ifnum);
8298+ printk(KERN_INFO "input: %s on usb%d:%d.%d\n",
8299+ mouse->name, dev->bus->busnum, dev->devnum, ifnum);
8300
8301 return mouse;
8302 }
8303diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/drivers/usb/wacom.c linux-modified/drivers/usb/wacom.c
8304--- linux-vanilla/drivers/usb/wacom.c Fri Nov 29 01:53:15 2002
8305+++ linux-modified/drivers/usb/wacom.c Mon Jan 6 16:48:21 2003
8306@@ -491,8 +491,8 @@
8307 usb_set_report(dev, ifnum, 3, 5, rep_data, 0);
8308 usb_set_report(dev, ifnum, 3, 6, rep_data, 0);
8309
8310- printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
8311- wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
8312+ printk(KERN_INFO "input: %s on usb%d:%d.%d\n",
8313+ wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
8314
8315 return wacom;
8316 }
8317diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/include/linux/hiddev.h linux-modified/include/linux/hiddev.h
8318--- linux-vanilla/include/linux/hiddev.h Fri Nov 29 01:53:15 2002
8319+++ linux-modified/include/linux/hiddev.h Sun Mar 9 17:01:16 2003
8320@@ -2,7 +2,7 @@
8321 #define _HIDDEV_H
8322
8323 /*
8324- * $Id$
8325+ * $Id$
8326 *
8327 * Copyright (c) 1999-2000 Vojtech Pavlik
8328 *
8329@@ -25,8 +25,8 @@
8330 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8331 *
8332 * Should you need to contact me, the author, you can do so either by
8333- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
8334- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
8335+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
8336+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
8337 */
8338
8339 /*
8340@@ -119,12 +119,17 @@
8341 __s32 value;
8342 };
8343
8344+/* FIELD_INDEX_NONE is returned in read() data from the kernel when flags
8345+ * is set to (HIDDEV_FLAG_UREF | HIDDEV_FLAG_REPORT) and a new report has
8346+ * been sent by the device
8347+ */
8348+#define HID_FIELD_INDEX_NONE 0xffffffff
8349
8350 /*
8351 * Protocol version.
8352 */
8353
8354-#define HID_VERSION 0x010002
8355+#define HID_VERSION 0x010003
8356
8357 /*
8358 * IOCTLs (0x00 - 0x7f)
8359@@ -138,11 +143,20 @@
8360 #define HIDIOCGNAME(len) _IOC(_IOC_READ, 'H', 0x06, len)
8361 #define HIDIOCGREPORT _IOW('H', 0x07, struct hiddev_report_info)
8362 #define HIDIOCSREPORT _IOW('H', 0x08, struct hiddev_report_info)
8363-#define HIDIOCGREPORTINFO _IOWR('H', 0x09, struct hiddev_report_info)
8364-#define HIDIOCGFIELDINFO _IOWR('H', 0x0A, struct hiddev_field_info)
8365-#define HIDIOCGUSAGE _IOWR('H', 0x0B, struct hiddev_usage_ref)
8366-#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref)
8367-#define HIDIOCGUCODE _IOWR('H', 0x0D, struct hiddev_usage_ref)
8368+#define HIDIOCGREPORTINFO _IOWR('H', 0x09, struct hiddev_report_info)
8369+#define HIDIOCGFIELDINFO _IOWR('H', 0x0A, struct hiddev_field_info)
8370+#define HIDIOCGUSAGE _IOWR('H', 0x0B, struct hiddev_usage_ref)
8371+#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref)
8372+#define HIDIOCGUCODE _IOWR('H', 0x0D, struct hiddev_usage_ref)
8373+#define HIDIOCGFLAG _IOR('H', 0x0E, int)
8374+#define HIDIOCSFLAG _IOW('H', 0x0F, int)
8375+
8376+/*
8377+ * Flags to be used in HIDIOCSFLAG
8378+ */
8379+#define HIDDEV_FLAG_UREF 0x1
8380+#define HIDDEV_FLAG_REPORT 0x2
8381+#define HIDDEV_FLAGS 0x3
8382
8383 /* To traverse the input report descriptor info for a HID device, perform the
8384 * following:
8385@@ -179,13 +193,13 @@
8386 #ifdef CONFIG_USB_HIDDEV
8387 int hiddev_connect(struct hid_device *);
8388 void hiddev_disconnect(struct hid_device *);
8389-void hiddev_hid_event(struct hid_device *, unsigned int usage, int value);
8390+void hiddev_hid_event(struct hid_device *, struct hiddev_usage_ref *ref);
8391 int __init hiddev_init(void);
8392 void __exit hiddev_exit(void);
8393 #else
8394 static inline int hiddev_connect(struct hid_device *hid) { return -1; }
8395 static inline void hiddev_disconnect(struct hid_device *hid) { }
8396-static inline void hiddev_hid_event(struct hid_device *hid, unsigned int usage, int value) { }
8397+static inline void hiddev_hid_event(struct hid_device *, struct hiddev_usage_ref *ref) { }
8398 static inline int hiddev_init(void) { return 0; }
8399 static inline void hiddev_exit(void) { }
8400 #endif
8401diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/include/linux/input.h linux-modified/include/linux/input.h
8402--- linux-vanilla/include/linux/input.h Sun Jan 26 16:09:49 2003
8403+++ linux-modified/include/linux/input.h Sun Mar 9 16:58:14 2003
8404@@ -2,11 +2,9 @@
8405 #define _INPUT_H
8406
8407 /*
8408- * $Id$
8409+ * $Id$
8410 *
8411- * Copyright (c) 1999-2000 Vojtech Pavlik
8412- *
8413- * Sponsored by SuSE
8414+ * Copyright (c) 1999-2001 Vojtech Pavlik
8415 */
8416
8417 /*
8418@@ -17,7 +15,7 @@
8419 *
8420 * This program is distributed in the hope that it will be useful,
8421 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8422- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8423+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8424 * GNU General Public License for more details.
8425 *
8426 * You should have received a copy of the GNU General Public License
8427@@ -25,8 +23,8 @@
8428 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8429 *
8430 * Should you need to contact me, the author, you can do so either by
8431- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
8432- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
8433+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
8434+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
8435 */
8436
8437 #ifdef __KERNEL__
8438@@ -64,17 +62,20 @@
8439 #define EVIOCSREP _IOW('E', 0x03, int[2]) /* get repeat settings */
8440 #define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */
8441 #define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */
8442-#define EVIOCGKEY _IOR('E', 0x05, int[2]) /* get key value */
8443+
8444 #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
8445-#define EVIOCGBUS _IOR('E', 0x07, short[4]) /* get bus address */
8446+#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
8447+#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
8448+
8449+#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */
8450+#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
8451+#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
8452
8453 #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */
8454 #define EVIOCGABS(abs) _IOR('E', 0x40 + abs, int[5]) /* get abs value/limits */
8455
8456 #define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
8457 #define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
8458-#define EVIOCSGAIN _IOW('E', 0x82, unsigned short) /* Set overall gain */
8459-#define EVIOCSAUTOCENTER _IOW('E', 0x83, unsigned short) /* Enable or disable auto-centering */
8460 #define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
8461
8462 /*
8463@@ -90,6 +91,8 @@
8464 #define EV_SND 0x12
8465 #define EV_REP 0x14
8466 #define EV_FF 0x15
8467+#define EV_PWR 0x16
8468+#define EV_FF_STATUS 0x17
8469 #define EV_MAX 0x1f
8470
8471 /*
8472@@ -304,8 +307,27 @@
8473 #define KEY_PROG4 203
8474 #define KEY_SUSPEND 205
8475 #define KEY_CLOSE 206
8476+#define KEY_PLAY 207
8477+#define KEY_FASTFORWARD 208
8478+#define KEY_BASSBOOST 209
8479+#define KEY_PRINT 210
8480+#define KEY_HP 211
8481+#define KEY_CAMERA 212
8482+#define KEY_SOUND 213
8483+#define KEY_QUESTION 214
8484+#define KEY_EMAIL 215
8485+#define KEY_CHAT 216
8486+#define KEY_SEARCH 217
8487+#define KEY_CONNECT 218
8488+#define KEY_FINANCE 219
8489+#define KEY_SPORT 220
8490+#define KEY_SHOP 221
8491+#define KEY_ALTERASE 222
8492+#define KEY_CANCEL 223
8493+#define KEY_BRIGHTNESSDOWN 224
8494+#define KEY_BRIGHTNESSUP 225
8495
8496-#define KEY_UNKNOWN 220
8497+#define KEY_UNKNOWN 240
8498
8499 #define KEY_BRIGHTNESSDOWN 224
8500 #define KEY_BRIGHTNESSUP 225
8501@@ -376,6 +398,10 @@
8502 #define BTN_STYLUS 0x14b
8503 #define BTN_STYLUS2 0x14c
8504
8505+#define BTN_WHEEL 0x150
8506+#define BTN_GEAR_DOWN 0x150
8507+#define BTN_GEAR_UP 0x151
8508+
8509 #define KEY_MAX 0x1ff
8510
8511 /*
8512@@ -419,7 +445,8 @@
8513 #define ABS_TILT_X 0x1a
8514 #define ABS_TILT_Y 0x1b
8515 #define ABS_MISC 0x1c
8516-#define ABS_MAX 0x1f
8517+#define ABS_VOLUME 0x20
8518+#define ABS_MAX 0x3f
8519
8520 /*
8521 * Misc events
8522@@ -485,67 +512,89 @@
8523 #define BUS_I2C 0x18
8524
8525 /*
8526+ * Values describing the status of an effect
8527+ */
8528+#define FF_STATUS_STOPPED 0x00
8529+#define FF_STATUS_PLAYING 0x01
8530+#define FF_STATUS_MAX 0x01
8531+
8532+/*
8533 * Structures used in ioctls to upload effects to a device
8534 * The first structures are not passed directly by using ioctls.
8535 * They are sub-structures of the actually sent structure (called ff_effect)
8536 */
8537
8538 struct ff_replay {
8539- __u16 length; /* Duration of an effect */
8540+ __u16 length; /* Duration of an effect in ms.
8541+ All other times are also expressed in ms.
8542+ 0 means "play for ever" */
8543 __u16 delay; /* Time to wait before to start playing an effect */
8544 };
8545
8546 struct ff_trigger {
8547 __u16 button; /* Number of button triggering an effect */
8548- __u16 interval; /* Time to wait before an effect can be re-triggered */
8549+ __u16 interval; /* Time to wait before an effect can be re-triggered (ms) */
8550 };
8551
8552-struct ff_shape {
8553- __u16 attack_length; /* Duration of attack */
8554- __s16 attack_level; /* Level at beginning of attack */
8555- __u16 fade_length; /* Duration of fade */
8556- __s16 fade_level; /* Level at end of fade */
8557+struct ff_envelope {
8558+ __u16 attack_length; /* Duration of attack (ms) */
8559+ __u16 attack_level; /* Level at beginning of attack */
8560+ __u16 fade_length; /* Duration of fade (ms) */
8561+ __u16 fade_level; /* Level at end of fade */
8562 };
8563
8564 /* FF_CONSTANT */
8565 struct ff_constant_effect {
8566- __s16 level; /* Strength of effect */
8567- __u16 direction; /* Direction of effect (see periodic effects) */
8568- struct ff_shape shape;
8569+ __s16 level; /* Strength of effect. Negative values are OK */
8570+ struct ff_envelope envelope;
8571 };
8572
8573-/* FF_SPRING of FF_FRICTION */
8574-struct ff_interactive_effect {
8575-/* Axis along which effect must be created. If null, the field named direction
8576- * is used
8577- * It is a bit array (ie to enable axes X and Y, use BIT(ABS_X) | BIT(ABS_Y)
8578- */
8579- __u16 axis;
8580- __u16 direction;
8581+/* FF_RAMP */
8582+struct ff_ramp_effect {
8583+ __s16 start_level;
8584+ __s16 end_level;
8585+ struct ff_envelope envelope;
8586+};
8587
8588- __s16 right_saturation; /* Max level when joystick is on the right */
8589- __s16 left_saturation; /* Max level when joystick in on the left */
8590+/* FF_SPRING of FF_FRICTION */
8591+struct ff_condition_effect {
8592+ __u16 right_saturation; /* Max level when joystick is on the right */
8593+ __u16 left_saturation; /* Max level when joystick in on the left */
8594
8595 __s16 right_coeff; /* Indicates how fast the force grows when the
8596 joystick moves to the right */
8597 __s16 left_coeff; /* Same for left side */
8598
8599 __u16 deadband; /* Size of area where no force is produced */
8600- __s16 center; /* Position of dead dead zone */
8601+ __s16 center; /* Position of dead zone */
8602
8603 };
8604
8605 /* FF_PERIODIC */
8606 struct ff_periodic_effect {
8607 __u16 waveform; /* Kind of wave (sine, square...) */
8608- __u16 period;
8609+ __u16 period; /* in ms */
8610 __s16 magnitude; /* Peak value */
8611 __s16 offset; /* Mean value of wave (roughly) */
8612 __u16 phase; /* 'Horizontal' shift */
8613- __u16 direction; /* Direction. 0 deg -> 0x0000
8614- 90 deg -> 0x4000 */
8615
8616- struct ff_shape shape;
8617+ struct ff_envelope envelope;
8618+
8619+/* Only used if waveform == FF_CUSTOM */
8620+ __u32 custom_len; /* Number of samples */
8621+ __s16 *custom_data; /* Buffer of samples */
8622+/* Note: the data pointed by custom_data is copied by the driver. You can
8623+ * therefore dispose of the memory after the upload/update */
8624+};
8625+
8626+/* FF_RUMBLE */
8627+/* Some rumble pads have two motors of different weight.
8628+ strong_magnitude represents the magnitude of the vibration generated
8629+ by the heavy motor.
8630+*/
8631+struct ff_rumble_effect {
8632+ __u16 strong_magnitude; /* Magnitude of the heavy motor */
8633+ __u16 weak_magnitude; /* Magnitude of the light one */
8634 };
8635
8636 /*
8637@@ -554,36 +603,30 @@
8638 struct ff_effect {
8639 __u16 type;
8640 /* Following field denotes the unique id assigned to an effect.
8641- * It is set by the driver.
8642+ * If user sets if to -1, a new effect is created, and its id is returned in the same field
8643+ * Else, the user sets it to the effect id it wants to update.
8644 */
8645 __s16 id;
8646
8647+ __u16 direction; /* Direction. 0 deg -> 0x0000 (down)
8648+ 90 deg -> 0x4000 (left)
8649+ 180 deg -> 0x8000 (up)
8650+ 270 deg -> 0xC000 (right)
8651+ */
8652+
8653 struct ff_trigger trigger;
8654 struct ff_replay replay;
8655
8656 union {
8657 struct ff_constant_effect constant;
8658+ struct ff_ramp_effect ramp;
8659 struct ff_periodic_effect periodic;
8660- struct ff_interactive_effect interactive;
8661+ struct ff_condition_effect condition[2]; /* One for each axis */
8662+ struct ff_rumble_effect rumble;
8663 } u;
8664 };
8665
8666 /*
8667- * Buttons that can trigger effects. Use for example FF_BTN(BTN_TRIGGER) to
8668- * access the bitmap.
8669- */
8670-
8671-#define FF_BTN(x) ((x) - BTN_MISC + FF_BTN_OFFSET)
8672-#define FF_BTN_OFFSET 0x00
8673-
8674-/*
8675- * Force feedback axis mappings. Use FF_ABS() to access the bitmap.
8676- */
8677-
8678-#define FF_ABS(x) ((x) + FF_ABS_OFFSET)
8679-#define FF_ABS_OFFSET 0x40
8680-
8681-/*
8682 * Force feedback effect types
8683 */
8684
8685@@ -592,6 +635,9 @@
8686 #define FF_CONSTANT 0x52
8687 #define FF_SPRING 0x53
8688 #define FF_FRICTION 0x54
8689+#define FF_DAMPER 0x55
8690+#define FF_INERTIA 0x56
8691+#define FF_RAMP 0x57
8692
8693 /*
8694 * Force feedback periodic effect types
8695@@ -630,8 +676,9 @@
8696
8697 void *private;
8698
8699- int number;
8700 char *name;
8701+ char *phys;
8702+ char *uniq;
8703 unsigned short idbus;
8704 unsigned short idvendor;
8705 unsigned short idproduct;
8706@@ -654,6 +701,9 @@
8707 unsigned int repeat_key;
8708 struct timer_list timer;
8709
8710+ struct pm_dev *pm_dev;
8711+ int state;
8712+
8713 int abs[ABS_MAX + 1];
8714 int rep[REP_MAX + 1];
8715
8716@@ -668,6 +718,8 @@
8717
8718 int (*open)(struct input_dev *dev);
8719 void (*close)(struct input_dev *dev);
8720+ int (*accept)(struct input_dev *dev, struct file *file);
8721+ int (*flush)(struct input_dev *dev, struct file *file);
8722 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
8723 int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
8724 int (*erase_effect)(struct input_dev *dev, int effect_id);
8725@@ -676,16 +728,63 @@
8726 struct input_dev *next;
8727 };
8728
8729+/*
8730+ * Structure for hotplug & device<->driver matching.
8731+ */
8732+
8733+#define INPUT_DEVICE_ID_MATCH_BUS 1
8734+#define INPUT_DEVICE_ID_MATCH_VENDOR 2
8735+#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
8736+#define INPUT_DEVICE_ID_MATCH_VERSION 8
8737+
8738+#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010
8739+#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020
8740+#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040
8741+#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080
8742+#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100
8743+#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
8744+#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
8745+#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
8746+
8747+#define INPUT_DEVICE_ID_MATCH_DEVICE\
8748+ (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
8749+#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\
8750+ (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION)
8751+
8752+struct input_device_id {
8753+
8754+ unsigned long flags;
8755+
8756+ unsigned short idbus;
8757+ unsigned short idvendor;
8758+ unsigned short idproduct;
8759+ unsigned short idversion;
8760+
8761+ unsigned long evbit[NBITS(EV_MAX)];
8762+ unsigned long keybit[NBITS(KEY_MAX)];
8763+ unsigned long relbit[NBITS(REL_MAX)];
8764+ unsigned long absbit[NBITS(ABS_MAX)];
8765+ unsigned long mscbit[NBITS(MSC_MAX)];
8766+ unsigned long ledbit[NBITS(LED_MAX)];
8767+ unsigned long sndbit[NBITS(SND_MAX)];
8768+ unsigned long ffbit[NBITS(FF_MAX)];
8769+
8770+ unsigned long driver_info;
8771+};
8772+
8773 struct input_handler {
8774
8775 void *private;
8776
8777 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
8778- struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev);
8779+ struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id);
8780 void (*disconnect)(struct input_handle *handle);
8781
8782 struct file_operations *fops;
8783 int minor;
8784+ char *name;
8785+
8786+ struct input_device_id *id_table;
8787
8788 struct input_handle *handle;
8789 struct input_handler *next;
8790@@ -696,6 +795,7 @@
8791 void *private;
8792
8793 int open;
8794+ char *name;
8795
8796 struct input_dev *dev;
8797 struct input_handler *handler;
8798@@ -713,6 +813,9 @@
8799 int input_open_device(struct input_handle *);
8800 void input_close_device(struct input_handle *);
8801
8802+int input_accept_process(struct input_handle *handle, struct file *file);
8803+int input_flush_device(struct input_handle* handle, struct file* file);
8804+
8805 devfs_handle_t input_register_minor(char *name, int minor, int minor_base);
8806 void input_unregister_minor(devfs_handle_t handle);
8807
8808@@ -721,6 +824,8 @@
8809 #define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
8810 #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
8811 #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
8812+#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c)
8813+#define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c)
8814
8815 #endif
8816 #endif
8817diff -u -N -r --exclude=*.rej --exclude=CVS --exclude=.* --exclude=*~ linux-vanilla/include/linux/serio.h linux-modified/include/linux/serio.h
8818--- linux-vanilla/include/linux/serio.h Fri Nov 29 01:53:15 2002
8819+++ linux-modified/include/linux/serio.h Mon Jan 13 22:42:43 2003
8820@@ -2,38 +2,38 @@
8821 #define _SERIO_H
8822
8823 /*
8824- * $Id$
8825+ * $Id$
8826 *
8827- * Copyright (C) 1999 Vojtech Pavlik
8828- *
8829- * Sponsored by SuSE
8830+ * Copyright (C) 1999-2001 Vojtech Pavlik
8831 */
8832
8833 /*
8834 * This program is free software; you can redistribute it and/or modify
8835 * it under the terms of the GNU General Public License as published by
8836- * the Free Software Foundation; either version 2 of the License, or
8837+ * the Free Software Foundation; either version 2 of the License, or
8838 * (at your option) any later version.
8839- *
8840+ *
8841 * This program is distributed in the hope that it will be useful,
8842 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8843 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8844 * GNU General Public License for more details.
8845- *
8846+ *
8847 * You should have received a copy of the GNU General Public License
8848 * along with this program; if not, write to the Free Software
8849 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8850- *
8851+ *
8852 * Should you need to contact me, the author, you can do so either by
8853 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
8854- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
8855+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
8856 */
8857
8858 /*
8859 * The serial port set type ioctl.
8860 */
8861
8862+#include <asm/errno.h>
8863 #include <linux/ioctl.h>
8864+
8865 #define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
8866
8867 struct serio;
8868@@ -42,23 +42,30 @@
8869
8870 void *private;
8871 void *driver;
8872+ char *name;
8873+ char *phys;
8874+
8875+ unsigned short idbus;
8876+ unsigned short idvendor;
8877+ unsigned short idproduct;
8878+ unsigned short idversion;
8879
8880 unsigned long type;
8881- int number;
8882
8883 int (*write)(struct serio *, unsigned char);
8884 int (*open)(struct serio *);
8885 void (*close)(struct serio *);
8886
8887 struct serio_dev *dev;
8888-
8889 struct serio *next;
8890 };
8891
8892 struct serio_dev {
8893
8894 void *private;
8895+ char *name;
8896
8897+ void (*write_wakeup)(struct serio *);
8898 void (*interrupt)(struct serio *, unsigned char, unsigned int);
8899 void (*connect)(struct serio *, struct serio_dev *dev);
8900 void (*disconnect)(struct serio *);
8901@@ -77,7 +84,14 @@
8902
8903 static __inline__ int serio_write(struct serio *serio, unsigned char data)
8904 {
8905- return serio->write(serio, data);
8906+ return serio->write?serio->write(serio, data):-ENOSYS;
8907+}
8908+
8909+static __inline__ void serio_dev_write_wakeup(struct serio *serio)
8910+{
8911+ if (serio->dev && serio->dev->write_wakeup) {
8912+ serio->dev->write_wakeup(serio);
8913+ }
8914 }
8915
8916 #define SERIO_TIMEOUT 1
8917@@ -109,6 +123,8 @@
8918 #define SERIO_STOWAWAY 0x20
8919 #define SERIO_H3600 0x21
8920 #define SERIO_PS2SER 0x22
8921+#define SERIO_TWIDKBD 0x23
8922+#define SERIO_TWIDJOY 0x24
8923 #define SERIO_HIL 0x25
8924
8925 #define SERIO_ID 0xff00UL
This page took 1.148669 seconds and 4 git commands to generate.