1 diff -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
5 Force feedback for Linux.
6 By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
8 +You may redistribute this file. Please remember to include shape.fig and
9 +interactive.fig as well.
10 ----------------------------------------------------------------------------
15 You then need to insert the modules into the following order:
18 +% modprobe serport # Only for serial
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.
27 Please check that you have all the /dev/input entries needed:
31 There is an utility called fftest that will allow you to test the driver.
32 -% fftest /dev/eventXX
33 +% fftest /dev/input/eventXX
35 3. Instructions to the developper
36 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38 #include <linux/input.h>
39 #include <sys/ioctl.h>
41 +unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
42 int ioctl(int file_descriptor, int request, unsigned long *features);
44 -"request" must be EVIOCGBIT(EV_FF, sizeof(unsigned long))
45 +"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
47 Returns the features supported by the device. features is a bitfield with the
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
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
69 +int ioctl(int fd, EVIOCGEFFECTS, int *n);
71 +Returns the number of effects the device can keep in its memory.
73 3.2 Uploading effects to the device
74 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
86 3.3 Removing an effect from the device
87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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;
112 +/* Set to EV_FF_STATUS */
113 + unsigned short type;
115 +/* Contains the id of the effect */
116 + unsigned short code;
118 +/* Indicates the status */
119 + unsigned int value;
122 +FF_STATUS_STOPPED The effect stopped playing
123 +FF_STATUS_PLAYING The effect started to play
124 diff -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
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
170 diff -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
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>
180 ----------------------------------------------------------------------------
184 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
192 For your convenience, the GNU General Public License version 2 is included
193 in the package: See the file COPYING.
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
201 2.5 Verifying that it works
202 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
203 @@ -503,15 +503,16 @@
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:
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
221 To use it, you need to attach the serial port to the driver using the
226 The I-Force driver now supports force feedback via the event interface.
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.
232 3.22 Gravis Stinger gamepad
233 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
234 diff -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
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
303 diff -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
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
316 diff -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
321 export-objs := serio.o gameport.o pcigame.o
323 -# I-Force may need both USB and RS-232
325 -ifeq ($(CONFIG_INPUT_IFORCE_232),m)
326 - ifeq ($(CONFIG_INPUT_IFORCE_USB),y)
327 - CONFIG_INPUT_IFORCE_USB := m
330 -ifeq ($(CONFIG_INPUT_IFORCE_USB),m)
331 - ifeq ($(CONFIG_INPUT_IFORCE_232),y)
332 - CONFIG_INPUT_IFORCE_232 := m
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
346 obj-$(CONFIG_INPUT_ANALOG) += analog.o
347 obj-$(CONFIG_INPUT_A3D) += a3d.o
349 obj-$(CONFIG_INPUT_TURBOGRAFX) += turbografx.o
351 obj-$(CONFIG_INPUT_AMIJOY) += amijoy.o
353 +subdir-$(CONFIG_JOYSTICK_IFORCE) += iforce
355 # The global Rules.make.
357 diff -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
361 a3d->dev.idversion = 0x0100;
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);
370 fail2: gameport_close(gameport);
371 diff -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
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);
385 diff -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
390 input_register_device(&analog->dev);
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);
398 printk(" [ADC port]\n");
399 diff -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
403 cobra->dev[i].absmin[ABS_Y] = -1; cobra->dev[i].absmax[ABS_Y] = 1;
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);
413 diff -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
417 db9->dev[i].absmin[ABS_Y] = -1; db9->dev[i].absmax[ABS_Y] = 1;
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);
427 diff -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
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);
439 diff -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
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);
452 fail2: gameport_close(gameport);
453 diff -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
458 input_register_device(grip->dev + i);
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);
467 diff -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
471 +CONFIG_JOYSTICK_IFORCE
472 + Say Y here if you have an I-Force joystick or steering wheel
474 + You also must choose at least one of the two options below.
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>.
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.
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.
489 + You will need an additional utility called inputattach, see
490 + Documentation/input/joystick.txt and ff.txt.
492 diff -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
497 +# I-Force driver configuration
500 +dep_tristate 'I-Force devices' CONFIG_JOYSTICK_IFORCE $CONFIG_INPUT $CONFIG_INPUT_JOYSTICK
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
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
510 diff -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
515 +# Makefile for the I-Force driver
517 +# By Johann Deneux <deneux@ifrance.com>
521 +list-multi := iforce.o
522 +iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o
524 +obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
526 +ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y)
527 + iforce-objs += iforce-serio.o
530 +ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y)
531 + iforce-objs += iforce-usb.o
534 +EXTRA_CFLAGS = -Werror-implicit-function-declaration
536 +# The global Rules.make.
538 +include $(TOPDIR)/Rules.make
541 +iforce.o: $(iforce-objs)
542 + $(LD) -r -o $@ $(iforce-objs)
544 diff -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
551 + * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
552 + * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
554 + * USB/RS232 I-Force joysticks and wheels.
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.
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.
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
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
580 + * Set the magnitude of a constant force effect
581 + * Return error code
583 + * Note: caller must ensure exclusive access to device
586 +static int make_magnitude_modifier(struct iforce* iforce,
587 + struct resource* mod_chunk, int no_alloc, __s16 level)
589 + unsigned char data[3];
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,
596 + up(&iforce->mem_mutex);
599 + up(&iforce->mem_mutex);
602 + data[0] = LO(mod_chunk->start);
603 + data[1] = HI(mod_chunk->start);
604 + data[2] = HIFIX80(level);
606 + iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data);
608 +// iforce_dump_packet("magnitude: ", FF_CMD_MAGNITUDE, data);
613 + * Upload the component of an effect dealing with the period, phase and magnitude
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)
620 + unsigned char data[7];
622 + period = TIME_SCALE(period);
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,
629 + up(&iforce->mem_mutex);
632 + up(&iforce->mem_mutex);
635 + data[0] = LO(mod_chunk->start);
636 + data[1] = HI(mod_chunk->start);
638 + data[2] = HIFIX80(magnitude);
639 + data[3] = HIFIX80(offset);
640 + data[4] = HI(phase);
642 + data[5] = LO(period);
643 + data[6] = HI(period);
645 + iforce_send_packet(iforce, FF_CMD_PERIOD, data);
651 + * Uploads the part of an effect setting the envelope of the force
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)
659 + unsigned char data[8];
661 + attack_duration = TIME_SCALE(attack_duration);
662 + fade_duration = TIME_SCALE(fade_duration);
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,
669 + up(&iforce->mem_mutex);
672 + up(&iforce->mem_mutex);
675 + data[0] = LO(mod_chunk->start);
676 + data[1] = HI(mod_chunk->start);
678 + data[2] = LO(attack_duration);
679 + data[3] = HI(attack_duration);
680 + data[4] = HI(initial_level);
682 + data[5] = LO(fade_duration);
683 + data[6] = HI(fade_duration);
684 + data[7] = HI(final_level);
686 + iforce_send_packet(iforce, FF_CMD_ENVELOPE, data);
692 + * Component of spring, friction, inertia... effects
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)
699 + unsigned char data[10];
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,
706 + up(&iforce->mem_mutex);
709 + up(&iforce->mem_mutex);
712 + data[0] = LO(mod_chunk->start);
713 + data[1] = HI(mod_chunk->start);
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 */
718 + center = (500*center)>>15;
719 + data[4] = LO(center);
720 + data[5] = HI(center);
722 + db = (1000*db)>>16;
726 + data[8] = (100*rsat)>>16;
727 + data[9] = (100*lsat)>>16;
729 + iforce_send_packet(iforce, FF_CMD_CONDITION, data);
730 +// iforce_dump_packet("condition", FF_CMD_CONDITION, data);
735 +static unsigned char find_button(struct iforce *iforce, signed short button)
738 + for (i = 1; iforce->type->btn[i] >= 0; i++)
739 + if (iforce->type->btn[i] == button)
745 + * Analyse the changes in an effect, and tell if we need to send an condition
748 +static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
751 + struct ff_effect* old = &iforce->core_effects[id].effect;
755 + if (new->type != FF_SPRING && new->type != FF_FRICTION) {
756 + printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
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;
772 + * Analyse the changes in an effect, and tell if we need to send a magnitude
775 +static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect)
777 + int id = effect->id;
778 + struct ff_effect* old = &iforce->core_effects[id].effect;
780 + if (effect->type != FF_CONSTANT) {
781 + printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
785 + return (old->u.constant.level != effect->u.constant.level);
789 + * Analyse the changes in an effect, and tell if we need to send an envelope
792 +static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect)
794 + int id = effect->id;
795 + struct ff_effect* old = &iforce->core_effects[id].effect;
797 + switch (effect->type) {
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)
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)
815 + printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
822 + * Analyse the changes in an effect, and tell if we need to send a periodic
825 +static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
828 + struct ff_effect* old = &iforce->core_effects[id].effect;
830 + if (new->type != FF_PERIODIC) {
831 + printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");
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);
842 + * Analyse the changes in an effect, and tell if we need to send an effect
845 +static int need_core(struct iforce* iforce, struct ff_effect* new)
848 + struct ff_effect* old = &iforce->core_effects[id].effect;
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)
860 + * Send the part common to all effects to the device
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)
866 + unsigned char data[14];
868 + duration = TIME_SCALE(duration);
869 + delay = TIME_SCALE(delay);
870 + interval = TIME_SCALE(interval);
873 + data[1] = effect_type;
874 + data[2] = LO(axes) | find_button(iforce, button);
876 + if (!duration) duration = 0xFFFF;
877 + data[3] = LO(duration);
878 + data[4] = HI(duration);
880 + data[5] = HI(direction);
882 + data[6] = LO(interval);
883 + data[7] = HI(interval);
885 + data[8] = LO(mod_id1);
886 + data[9] = HI(mod_id1);
887 + data[10] = LO(mod_id2);
888 + data[11] = HI(mod_id2);
890 + data[12] = LO(delay);
891 + data[13] = HI(delay);
894 +/* iforce_control_playback(iforce, id, 0);*/
896 + iforce_send_packet(iforce, FF_CMD_EFFECT, data);
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);
908 + * Upload a periodic effect to the device
909 + * See also iforce_upload_constant.
911 +int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update)
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;
922 + if (!is_update || need_period_modifier(iforce, effect)) {
923 + param1_err = make_period_modifier(iforce, mod1_chunk,
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);
931 + if (!is_update || need_envelope_modifier(iforce, effect)) {
932 + param2_err = make_envelope_modifier(iforce, mod2_chunk,
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);
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;
951 + if (!is_update || need_core(iforce, effect)) {
952 + core_err = make_core(iforce, effect->id,
957 + effect->replay.length,
958 + effect->replay.delay,
959 + effect->trigger.button,
960 + effect->trigger.interval,
961 + effect->direction);
964 + /* If one of the parameter creation failed, we already returned an
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;
970 + return core_err < 0 ? core_err : (param1_err && param2_err);
974 + * Upload a constant force effect
977 + * 0 Ok, effect created or updated
978 + * 1 effect did not change since last upload, and no packet was therefore sent
980 +int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update)
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;
990 + if (!is_update || need_magnitude_modifier(iforce, effect)) {
991 + param1_err = make_magnitude_modifier(iforce, mod1_chunk,
993 + effect->u.constant.level);
994 + if (param1_err) return param1_err;
995 + set_bit(FF_MOD1_IS_USED, core_effect->flags);
998 + if (!is_update || need_envelope_modifier(iforce, effect)) {
999 + param2_err = make_envelope_modifier(iforce, mod2_chunk,
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);
1009 + if (!is_update || need_core(iforce, effect)) {
1010 + core_err = make_core(iforce, effect->id,
1011 + mod1_chunk->start,
1012 + mod2_chunk->start,
1015 + effect->replay.length,
1016 + effect->replay.delay,
1017 + effect->trigger.button,
1018 + effect->trigger.interval,
1019 + effect->direction);
1022 + /* If one of the parameter creation failed, we already returned an
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;
1028 + return core_err < 0 ? core_err : (param1_err && param2_err);
1032 + * Upload an condition effect. Those are for example friction, inertia, springs...
1034 +int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update)
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);
1041 + int param_err = 1;
1044 + switch (effect->type) {
1045 + case FF_SPRING: type = 0x40; break;
1046 + case FF_DAMPER: type = 0x41; break;
1047 + default: return -1;
1050 + if (!is_update || need_condition_modifier(iforce, effect)) {
1051 + param_err = make_condition_modifier(iforce, mod1_chunk,
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);
1062 + param_err = make_condition_modifier(iforce, mod2_chunk,
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);
1075 + if (!is_update || need_core(iforce, effect)) {
1076 + core_err = make_core(iforce, effect->id,
1077 + mod1_chunk->start, mod2_chunk->start,
1079 + effect->replay.length, effect->replay.delay,
1080 + effect->trigger.button, effect->trigger.interval,
1081 + effect->direction);
1084 + /* If the parameter creation failed, we already returned an
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;
1090 + return core_err < 0 ? core_err : param_err;
1092 diff -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
1099 + * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
1100 + * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
1102 + * USB/RS232 I-Force joysticks and wheels.
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.
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.
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
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
1125 +#include "iforce.h"
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");
1131 +#define USB_VENDOR_ID_SAITEK 0x06a3
1132 +#define USB_PRODUCT_ID_CYBORGFORCE 0xff12
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 };
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 };
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 };
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 };
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 };
1155 +static signed short abs_joystick[] =
1156 +{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
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 };
1162 +static signed short abs_wheel[] =
1163 +{ ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, -1 };
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 };
1169 +static signed short abs_saitek_joystick[] =
1170 +{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER,ABS_HAT0X, ABS_HAT0Y, -1 };
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 };
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 }
1195 +static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
1197 + struct iforce* iforce = (struct iforce*)(dev->private);
1198 + unsigned char data[3];
1200 + if (type != EV_FF)
1207 + data[0] = value >> 9;
1208 + iforce_send_packet(iforce, FF_CMD_GAIN, data);
1212 + case FF_AUTOCENTER:
1215 + data[1] = value >> 9;
1216 + iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
1220 + iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
1224 + default: /* Play or stop an effect */
1227 + set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
1230 + clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
1233 + iforce_control_playback(iforce, code, value);
1241 + * Function called when an ioctl is performed on the event dev entry.
1242 + * It uploads an effect to the device
1244 +static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
1246 + struct iforce* iforce = (struct iforce*)(dev->private);
1251 +/* Check this effect type is supported by this device */
1252 + if (!test_bit(effect->type, iforce->dev.ffbit))
1256 + * If we want to create a new effect, get a free id
1258 + if (effect->id == -1) {
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;
1263 + if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
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 */
1270 + is_update = FALSE;
1273 + /* We want to update an effect */
1274 + /* Parameter type cannot be updated */
1275 + if (effect->type != iforce->core_effects[effect->id].effect.type)
1278 + /* Check the effect is not already being updated */
1279 + if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) {
1287 + * Upload the effect
1289 + switch (effect->type) {
1292 + ret = iforce_upload_periodic(iforce, effect, is_update);
1296 + ret = iforce_upload_constant(iforce, effect, is_update);
1301 + ret = iforce_upload_condition(iforce, effect, is_update);
1308 + /* A packet was sent, forbid new updates until we are notified
1309 + * that the packet was updated
1311 + set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags);
1313 + iforce->core_effects[effect->id].effect = *effect;
1318 + * Erases an effect: it frees the effect id and mark as unused the memory
1319 + * allocated for the parameters
1321 +static int iforce_erase_effect(struct input_dev *dev, int effect_id)
1323 + struct iforce* iforce = (struct iforce*)(dev->private);
1325 + struct iforce_core_effect* core_effect;
1327 + if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
1330 + core_effect = iforce->core_effects + effect_id;
1332 + if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
1333 + err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk));
1335 + if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
1336 + err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk));
1338 + /*TODO: remember to change that if more FF_MOD* bits are added */
1339 + core_effect->flags[0] = 0;
1344 +static int iforce_open(struct input_dev *dev)
1346 + struct iforce *iforce = dev->private;
1348 + switch (iforce->bus) {
1349 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1351 + iforce->irq->dev = iforce->usbdev;
1352 + if (usb_submit_urb(iforce->irq))
1358 + /* Enable force feedback */
1359 + iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
1364 +static int iforce_flush(struct input_dev *dev, struct file *file)
1366 + struct iforce *iforce = dev->private;
1369 + /* Erase all effects this process owns */
1370 + for (i=0; i<dev->ff_effects_max; ++i) {
1372 + if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
1373 + current->pid == iforce->core_effects[i].owner) {
1376 + input_report_ff(dev, i, 0);
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);
1388 +static void iforce_release(struct input_dev *dev)
1390 + struct iforce *iforce = dev->private;
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))
1398 + if (i<dev->ff_effects_max) {
1399 + printk(KERN_WARNING "iforce_release: Device still owns effects\n");
1402 + /* Disable force feedback playback */
1403 + iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
1405 + switch (iforce->bus) {
1406 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1408 + usb_unlink_urb(iforce->irq);
1410 + /* The device was unplugged before the file
1412 + if (iforce->usbdev == NULL) {
1413 + iforce_delete_device(iforce);
1421 +void iforce_delete_device(struct iforce *iforce)
1423 + switch (iforce->bus) {
1424 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1426 + iforce_usb_delete(iforce);
1429 +#ifdef CONFIG_JOYSTICK_IFORCE_232
1431 + //TODO: Wait for the last packets to be sent
1437 +int iforce_init_device(struct iforce *iforce)
1439 + unsigned char c[] = "CEOV";
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;
1447 + iforce->dev.ff_effects_max = 10;
1450 + * Input device fields.
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;
1464 + * On-device memory allocation.
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;
1476 + * Wait until device ready - until it sends its first response.
1479 + for (i = 0; i < 20; i++)
1480 + if (!iforce_get_id_packet(iforce, "O"))
1483 + if (i == 20) { /* 5 seconds */
1484 + printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n");
1489 + * Get device info.
1492 + if (!iforce_get_id_packet(iforce, "M"))
1493 + iforce->dev.idvendor = (iforce->edata[2] << 8) | iforce->edata[1];
1495 + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n");
1497 + if (!iforce_get_id_packet(iforce, "P"))
1498 + iforce->dev.idproduct = (iforce->edata[2] << 8) | iforce->edata[1];
1500 + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n");
1502 + if (!iforce_get_id_packet(iforce, "B"))
1503 + iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
1505 + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
1507 + if (!iforce_get_id_packet(iforce, "N"))
1508 + iforce->dev.ff_effects_max = iforce->edata[1];
1510 + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
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;
1520 + * Display additional info.
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);
1528 + * Disable spring, enable force feedback.
1529 + * FIXME: We should use iforce_set_autocenter() et al here.
1532 + iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
1535 + * Find appropriate device entry
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)
1543 + iforce->type = iforce_device + i;
1544 + iforce->dev.name = iforce->type->name;
1547 + * Set input device bitfields and ranges.
1550 + iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
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);
1556 + set_bit(BTN_DEAD, iforce->dev.keybit);
1558 + for (i = 0; iforce->type->abs[i] >= 0; i++) {
1560 + signed short t = iforce->type->abs[i];
1561 + set_bit(t, iforce->dev.absbit);
1568 + if (iforce->dev.idvendor == USB_VENDOR_ID_SAITEK && iforce->dev.idproduct == USB_PRODUCT_ID_CYBORGFORCE)
1570 + iforce->dev.absmax[t] = 0x1000;
1571 + iforce->dev.absmin[t] = 0;
1574 + iforce->dev.absmax[t] = 1920;
1575 + iforce->dev.absmin[t] = -1920;
1577 + iforce->dev.absflat[t] = 128;
1578 + iforce->dev.absfuzz[t] = 16;
1579 + set_bit(t, iforce->dev.ffbit);
1582 + case ABS_THROTTLE:
1586 + iforce->dev.absmax[t] = 255;
1587 + iforce->dev.absmin[t] = 0;
1591 + if (iforce->dev.idvendor == USB_VENDOR_ID_SAITEK && iforce->dev.idproduct == USB_PRODUCT_ID_CYBORGFORCE)
1593 + iforce->dev.absmax[t] = 255;
1594 + iforce->dev.absmin[t] = 0;
1595 + iforce->dev.absflat[t] = 10;
1596 + iforce->dev.absfuzz[t] = 4;
1601 + iforce->dev.absmax[t] = 127;
1602 + iforce->dev.absmin[t] = -128;
1611 + iforce->dev.absmax[t] = 1;
1612 + iforce->dev.absmin[t] = -1;
1617 + for (i = 0; iforce->type->ff[i] >= 0; i++)
1618 + set_bit(iforce->type->ff[i], iforce->dev.ffbit);
1621 + * Register input device.
1624 + input_register_device(&iforce->dev);
1626 + printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
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);
1635 +static int __init iforce_init(void)
1637 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1638 + usb_register(&iforce_usb_driver);
1640 +#ifdef CONFIG_JOYSTICK_IFORCE_232
1641 + serio_register_device(&iforce_serio_dev);
1646 +static void __exit iforce_exit(void)
1648 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1649 + usb_deregister(&iforce_usb_driver);
1651 +#ifdef CONFIG_JOYSTICK_IFORCE_232
1652 + serio_unregister_device(&iforce_serio_dev);
1656 +module_init(iforce_init);
1657 +module_exit(iforce_exit);
1658 diff -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
1665 + * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
1666 + * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
1668 + * USB/RS232 I-Force joysticks and wheels.
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.
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.
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
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
1691 +#include "iforce.h"
1696 +} iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
1699 +void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data)
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]);
1710 + * Send a packet of bytes to the device
1712 +int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
1714 + /* Copy data to buffer */
1719 + unsigned long flags;
1722 + * Update head and tail of xmit buffer
1724 + spin_lock_irqsave(&iforce->xmit_lock, flags);
1726 + head = iforce->xmit.head;
1727 + tail = iforce->xmit.tail;
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);
1735 + empty = head == tail;
1736 + XMIT_INC(iforce->xmit.head, n+2);
1739 + * Store packet in xmit buffer
1741 + iforce->xmit.buf[head] = HI(cmd);
1742 + XMIT_INC(head, 1);
1743 + iforce->xmit.buf[head] = LO(cmd);
1744 + XMIT_INC(head, 1);
1746 + c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE);
1749 + memcpy(&iforce->xmit.buf[head],
1753 + memcpy(&iforce->xmit.buf[0],
1757 + XMIT_INC(head, n);
1759 + spin_unlock_irqrestore(&iforce->xmit_lock, flags);
1761 + * If necessary, start the transmission
1763 + switch (iforce->bus) {
1765 +#ifdef CONFIG_JOYSTICK_IFORCE_232
1768 + iforce_serial_xmit(iforce);
1771 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1774 + if (iforce->usbdev && empty &&
1775 + !test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
1777 + iforce_usb_xmit(iforce);
1785 +/* Start or stop an effect */
1786 +int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value)
1788 + unsigned char data[3];
1790 +//printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value);
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);
1798 +/* Mark an effect that was being updated as ready. That means it can be updated
1800 +static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
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);
1811 + printk(KERN_WARNING "iforce-packets.c: unused effect %04x updated !!!\n", addr);
1815 +void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
1817 + struct input_dev *dev = &iforce->dev;
1819 + static int being_used = 0;
1822 + printk(KERN_WARNING "iforce-packets.c: re-entrant call to iforce_process %d\n", being_used);
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);
1835 + if (!iforce->type) {
1840 + switch (HI(cmd)) {
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]);
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]);
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]);
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);
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)));
1869 + /* If there are untouched bits left, interpret them as the second hat */
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);
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);
1886 + case 0x02: /* status report */
1887 + input_report_key(dev, BTN_DEAD, data[0] & 0x02);
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);
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);
1901 + if (LO(cmd) > 3) {
1903 + for (j=3; j<LO(cmd); j+=2) {
1904 + mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
1912 +int iforce_get_id_packet(struct iforce *iforce, char *packet)
1914 + DECLARE_WAITQUEUE(wait, current);
1915 + int timeout = HZ; /* 1 second */
1917 + switch (iforce->bus) {
1921 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
1922 + iforce->dr.bRequest = packet[0];
1923 + iforce->ctrl->dev = iforce->usbdev;
1925 + set_current_state(TASK_INTERRUPTIBLE);
1926 + add_wait_queue(&iforce->wait, &wait);
1928 + if (usb_submit_urb(iforce->ctrl)) {
1929 + set_current_state(TASK_RUNNING);
1930 + remove_wait_queue(&iforce->wait, &wait);
1934 + while (timeout && iforce->ctrl->status == -EINPROGRESS)
1935 + timeout = schedule_timeout(timeout);
1937 + set_current_state(TASK_RUNNING);
1938 + remove_wait_queue(&iforce->wait, &wait);
1941 + usb_unlink_urb(iforce->ctrl);
1945 + printk(KERN_ERR "iforce_get_id_packet: iforce->bus = USB!\n");
1951 +#ifdef CONFIG_JOYSTICK_IFORCE_232
1952 + iforce->expect_packet = FF_CMD_QUERY;
1953 + iforce_send_packet(iforce, FF_CMD_QUERY, packet);
1955 + set_current_state(TASK_INTERRUPTIBLE);
1956 + add_wait_queue(&iforce->wait, &wait);
1958 + while (timeout && iforce->expect_packet)
1959 + timeout = schedule_timeout(timeout);
1961 + set_current_state(TASK_RUNNING);
1962 + remove_wait_queue(&iforce->wait, &wait);
1965 + iforce->expect_packet = 0;
1969 + printk(KERN_ERR "iforce_get_id_packet: iforce->bus = SERIO!\n");
1974 + printk(KERN_ERR "iforce_get_id_packet: iforce->bus = %d\n",
1979 + return -(iforce->edata[0] != packet[0]);
1982 diff -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
1989 + * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
1990 + * Copyright (c) 2001 Johann Deneux <deneux@ifrance.com>
1992 + * USB/RS232 I-Force joysticks and wheels.
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.
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.
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
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
2015 +#include "iforce.h"
2017 +void iforce_serial_xmit(struct iforce *iforce)
2021 + unsigned long flags;
2023 + if (test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
2024 + set_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags);
2028 + spin_lock_irqsave(&iforce->xmit_lock, flags);
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);
2039 + serio_write(iforce->serio, 0x2b);
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);
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);
2051 + serio_write(iforce->serio, cs);
2053 + if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
2056 + clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
2058 + spin_unlock_irqrestore(&iforce->xmit_lock, flags);
2061 +static void iforce_serio_write_wakeup(struct serio *serio)
2063 + iforce_serial_xmit((struct iforce *)serio->private);
2066 +static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
2068 + struct iforce* iforce = serio->private;
2070 + if (!iforce->pkt) {
2071 + if (data != 0x2b) {
2078 + if (!iforce->id) {
2079 + if (data > 3 && data != 0xff) {
2083 + iforce->id = data;
2087 + if (!iforce->len) {
2088 + if (data > IFORCE_MAX_LENGTH) {
2093 + iforce->len = data;
2097 + if (iforce->idx < iforce->len) {
2098 + iforce->csum += iforce->data[iforce->idx++] = data;
2102 + if (iforce->idx == iforce->len) {
2103 + iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
2112 +static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
2114 + struct iforce *iforce;
2115 + if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
2118 + if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return;
2119 + memset(iforce, 0, sizeof(struct iforce));
2121 + iforce->bus = IFORCE_232;
2122 + iforce->serio = serio;
2123 + serio->private = iforce;
2125 + if (serio_open(serio, dev)) {
2130 + if (iforce_init_device(iforce)) {
2131 + serio_close(serio);
2137 +static void iforce_serio_disconnect(struct serio *serio)
2139 + struct iforce* iforce = serio->private;
2141 + input_unregister_device(&iforce->dev);
2142 + serio_close(serio);
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,
2152 diff -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
2159 + * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
2160 + * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
2162 + * USB/RS232 I-Force joysticks and wheels.
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.
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.
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
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
2185 +#include "iforce.h"
2187 +void iforce_usb_xmit(struct iforce *iforce)
2190 + unsigned long flags;
2192 + spin_lock_irqsave(&iforce->xmit_lock, flags);
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);
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);
2205 + iforce->out->transfer_buffer_length = n + 1;
2206 + iforce->out->dev = iforce->usbdev;
2208 + /* Copy rest of data then */
2209 + c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE);
2212 + memcpy(iforce->out->transfer_buffer + 1,
2213 + &iforce->xmit.buf[iforce->xmit.tail],
2216 + memcpy(iforce->out->transfer_buffer + 1 + c,
2217 + &iforce->xmit.buf[0],
2220 + XMIT_INC(iforce->xmit.tail, n);
2222 + spin_unlock_irqrestore(&iforce->xmit_lock, flags);
2224 + if ( (n=usb_submit_urb(iforce->out)) ) {
2225 + printk(KERN_WARNING "iforce.c: iforce_usb_xmit: usb_submit_urb failed %d\n", n);
2229 +static void iforce_usb_irq(struct urb *urb)
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);
2237 +static void iforce_usb_out(struct urb *urb)
2239 + struct iforce *iforce = urb->context;
2241 + if (urb->status) {
2242 + printk(KERN_DEBUG "iforce_usb_out: urb->status %d, exiting", urb->status);
2246 + iforce_usb_xmit(iforce);
2248 + if (waitqueue_active(&iforce->wait))
2249 + wake_up(&iforce->wait);
2252 +static void iforce_usb_ctrl(struct urb *urb)
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);
2261 +static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum,
2262 + const struct usb_device_id *id)
2264 + struct usb_endpoint_descriptor *epirq, *epout;
2265 + struct iforce *iforce;
2267 + epirq = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
2268 + epout = dev->config[0].interface[ifnum].altsetting[0].endpoint + 1;
2270 + if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
2273 + memset(iforce, 0, sizeof(struct iforce));
2275 + if (!(iforce->irq = usb_alloc_urb(0))) {
2279 + if (!(iforce->out = usb_alloc_urb(0))) {
2283 + if (!(iforce->ctrl = usb_alloc_urb(0))) {
2287 + iforce->bus = IFORCE_USB;
2288 + iforce->usbdev = dev;
2290 + iforce->dr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
2291 + iforce->dr.wIndex = 0;
2292 + iforce->dr.wLength = 16;
2294 + usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
2295 + iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
2297 + usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
2298 + iforce + 1, 32, iforce_usb_out, iforce);
2300 + usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
2301 + (void*) &iforce->dr, iforce->edata, 16, iforce_usb_ctrl, iforce);
2303 + if (iforce_init_device(iforce)) goto fail;
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);
2318 +/* Called by iforce_delete() */
2319 +void iforce_usb_delete(struct iforce* iforce)
2321 + usb_unlink_urb(iforce->irq);
2322 + usb_unlink_urb(iforce->out);
2323 + usb_unlink_urb(iforce->ctrl);
2325 + usb_free_urb(iforce->irq);
2326 + usb_free_urb(iforce->out);
2327 + usb_free_urb(iforce->ctrl);
2330 +static void iforce_usb_disconnect(struct usb_device *dev, void *ptr)
2332 + struct iforce *iforce = ptr;
2333 + int open = iforce->dev.handle->open;
2335 + iforce->usbdev = NULL;
2336 + input_unregister_device(&iforce->dev);
2339 + iforce_delete_device(iforce);
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 */
2358 +MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
2360 +struct usb_driver iforce_usb_driver = {
2361 +// owner: THIS_MODULE,
2363 + probe: iforce_usb_probe,
2364 + disconnect: iforce_usb_disconnect,
2365 + id_table: iforce_usb_ids,
2367 diff -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
2374 + * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
2375 + * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
2377 + * USB/RS232 I-Force joysticks and wheels.
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.
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.
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
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
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>
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.
2416 +#include <linux/ioport.h>
2418 +#define IFORCE_MAX_LENGTH 16
2420 +#define IFORCE_232 1
2421 +#define IFORCE_USB 2
2426 +#define FF_EFFECTS_MAX 32
2428 +/* Each force feedback effect is made of one core effect, which can be
2429 + * associated to at most to effect modifiers
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
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)];
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
2450 + struct ff_effect effect;
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
2459 +#define FF_CMD_AUTOCENTER 0x4002
2460 +#define FF_CMD_PLAY 0x4103
2461 +#define FF_CMD_ENABLE 0x4201
2462 +#define FF_CMD_GAIN 0x4301
2464 +#define FF_CMD_QUERY 0xff01
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
2473 +struct iforce_device {
2477 + signed short *btn;
2478 + signed short *abs;
2483 + struct input_dev dev; /* Input device interface */
2484 + struct iforce_device *type;
2487 + unsigned char data[IFORCE_MAX_LENGTH];
2488 + unsigned char edata[IFORCE_MAX_LENGTH];
2490 + u16 expect_packet;
2492 +#ifdef CONFIG_JOYSTICK_IFORCE_232
2493 + struct serio *serio; /* RS232 transfer */
2494 + int idx, pkt, len, id;
2495 + unsigned char csum;
2497 +#ifdef CONFIG_JOYSTICK_IFORCE_USB
2498 + struct usb_device *usbdev; /* USB transfer */
2499 + struct urb *irq, *out, *ctrl;
2500 + struct usb_ctrlrequest dr;
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];
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;
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))
2519 +/* For many parameters, it seems that 0x80 is a special value that should
2520 + * be avoided. Instead, we replace this value by 0x7f
2522 +#define HIFIX80(a) ((unsigned char)(((a)<0? (a)+255 : (a))>>8))
2524 +/* Encode a time value */
2525 +#define TIME_SCALE(a) (a)
2528 +/* Public functions */
2529 +/* iforce-serio.c */
2530 +void iforce_serial_xmit(struct iforce *iforce);
2533 +void iforce_usb_xmit(struct iforce *iforce);
2534 +void iforce_usb_delete(struct iforce *iforce);
2536 +/* iforce-main.c */
2537 +int iforce_init_device(struct iforce *iforce);
2538 +void iforce_delete_device(struct iforce *iforce);
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);
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);
2552 +/* Public variables */
2553 +extern struct serio_dev iforce_serio_dev;
2554 +extern struct usb_driver iforce_usb_driver;
2555 diff -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
2562 - * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
2563 - * Copyright (c) 2001 Johann Deneux <deneux@ifrance.com>
2565 - * USB/RS232 I-Force joysticks and wheels.
2567 - * Sponsored by SuSE
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.
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.
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
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
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>
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.
2604 -#include <linux/ioport.h>
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");
2610 -#define IFORCE_MAX_LENGTH 16
2612 -#if defined(CONFIG_INPUT_IFORCE_232) || defined(CONFIG_INPUT_IFORCE_232_MODULE)
2613 -#define IFORCE_232 1
2615 -#if defined(CONFIG_INPUT_IFORCE_USB) || defined(CONFIG_INPUT_IFORCE_USB_MODULE)
2616 -#define IFORCE_USB 2
2619 -#define FF_EFFECTS_MAX 32
2621 -/* Each force feedback effect is made of one core effect, which can be
2622 - * associated to at most to effect modifiers
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
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)];
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
2643 -#define FF_CMD_AUTOCENTER 0x4002
2644 -#define FF_CMD_PLAY 0x4103
2645 -#define FF_CMD_ENABLE 0x4201
2646 -#define FF_CMD_GAIN 0x4301
2648 -#define FF_CMD_QUERY 0xff01
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 };
2659 -static struct iforce_device {
2663 - signed short *btn;
2664 - signed short *abs;
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 }
2676 - struct input_dev dev; /* Input device interface */
2677 - struct iforce_device *type;
2682 - unsigned char data[IFORCE_MAX_LENGTH];
2683 - unsigned char edata[IFORCE_MAX_LENGTH];
2685 - u16 expect_packet;
2688 - struct serio *serio; /* RS232 transfer */
2689 - int idx, pkt, len, id;
2690 - unsigned char csum;
2693 - struct usb_device *usbdev; /* USB transfer */
2694 - struct urb irq, out, ctrl;
2695 - struct usb_ctrlrequest dr;
2697 - /* Force Feedback */
2698 - wait_queue_head_t wait;
2699 - struct resource device_memory;
2700 - struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
2706 -} iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
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))
2712 -/* Encode a time value */
2713 -#define TIME_SCALE(a) ((a) == 0xffff ? 0xffff : (a) * 1000 / 256)
2715 -static void dump_packet(char *msg, u16 cmd, unsigned char *data)
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]);
2726 - * Send a packet of bytes to the device
2728 -static void send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
2730 - switch (iforce->bus) {
2733 - case IFORCE_232: {
2736 - unsigned char csum = 0x2b ^ HI(cmd) ^ LO(cmd);
2738 - serio_write(iforce->serio, 0x2b);
2739 - serio_write(iforce->serio, HI(cmd));
2740 - serio_write(iforce->serio, LO(cmd));
2742 - for (i = 0; i < LO(cmd); i++) {
2743 - serio_write(iforce->serio, data[i]);
2744 - csum = csum ^ data[i];
2747 - serio_write(iforce->serio, csum);
2752 - case IFORCE_USB: {
2754 - DECLARE_WAITQUEUE(wait, current);
2755 - int timeout = HZ; /* 1 second */
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;
2762 - set_current_state(TASK_INTERRUPTIBLE);
2763 - add_wait_queue(&iforce->wait, &wait);
2765 - if (usb_submit_urb(&iforce->out)) {
2766 - set_current_state(TASK_RUNNING);
2767 - remove_wait_queue(&iforce->wait, &wait);
2771 - while (timeout && iforce->out.status == -EINPROGRESS)
2772 - timeout = schedule_timeout(timeout);
2774 - set_current_state(TASK_RUNNING);
2775 - remove_wait_queue(&iforce->wait, &wait);
2778 - usb_unlink_urb(&iforce->out);
2786 -static void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
2788 - struct input_dev *dev = &iforce->dev;
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);
2801 - if (!iforce->type)
2804 - switch (HI(cmd)) {
2806 - case 0x01: /* joystick position data */
2807 - case 0x03: /* wheel position data */
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]);
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]);
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);
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)));
2827 - case 0x02: /* status report */
2829 - input_report_key(dev, BTN_DEAD, data[0] & 0x02);
2834 -static int get_id_packet(struct iforce *iforce, char *packet)
2836 - DECLARE_WAITQUEUE(wait, current);
2837 - int timeout = HZ; /* 1 second */
2839 - switch (iforce->bus) {
2844 - iforce->dr.bRequest = packet[0];
2845 - iforce->ctrl.dev = iforce->usbdev;
2847 - set_current_state(TASK_INTERRUPTIBLE);
2848 - add_wait_queue(&iforce->wait, &wait);
2850 - if (usb_submit_urb(&iforce->ctrl)) {
2851 - set_current_state(TASK_RUNNING);
2852 - remove_wait_queue(&iforce->wait, &wait);
2856 - while (timeout && iforce->ctrl.status == -EINPROGRESS)
2857 - timeout = schedule_timeout(timeout);
2859 - set_current_state(TASK_RUNNING);
2860 - remove_wait_queue(&iforce->wait, &wait);
2863 - usb_unlink_urb(&iforce->ctrl);
2872 - iforce->expect_packet = FF_CMD_QUERY;
2873 - send_packet(iforce, FF_CMD_QUERY, packet);
2875 - set_current_state(TASK_INTERRUPTIBLE);
2876 - add_wait_queue(&iforce->wait, &wait);
2878 - while (timeout && iforce->expect_packet)
2879 - timeout = schedule_timeout(timeout);
2881 - set_current_state(TASK_RUNNING);
2882 - remove_wait_queue(&iforce->wait, &wait);
2885 - iforce->expect_packet = 0;
2893 - return -(iforce->edata[0] != packet[0]);
2896 -static int iforce_open(struct input_dev *dev)
2898 - struct iforce *iforce = dev->private;
2900 - switch (iforce->bus) {
2903 - if (iforce->open++)
2905 - iforce->irq.dev = iforce->usbdev;
2906 - if (usb_submit_urb(&iforce->irq))
2914 -static void iforce_close(struct input_dev *dev)
2916 - struct iforce *iforce = dev->private;
2918 - switch (iforce->bus) {
2921 - if (!--iforce->open)
2922 - usb_unlink_urb(&iforce->irq);
2929 - * Start or stop playing an effect
2932 -static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
2934 - struct iforce* iforce = (struct iforce*)(dev->private);
2935 - unsigned char data[3];
2937 - printk(KERN_DEBUG "iforce.c: input_event(type = %d, code = %d, value = %d)\n", type, code, value);
2939 - if (type != EV_FF)
2946 - data[0] = value >> 9;
2947 - send_packet(iforce, FF_CMD_GAIN, data);
2951 - case FF_AUTOCENTER:
2954 - data[1] = value >> 9;
2955 - send_packet(iforce, FF_CMD_AUTOCENTER, data);
2959 - send_packet(iforce, FF_CMD_AUTOCENTER, data);
2963 - default: /* Play an effect */
2965 - if (code >= iforce->dev.ff_effects_max)
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);
2980 - * Set the magnitude of a constant force effect
2981 - * Return error code
2983 - * Note: caller must ensure exclusive access to device
2986 -static int make_magnitude_modifier(struct iforce* iforce,
2987 - struct resource* mod_chunk, __s16 level)
2989 - unsigned char data[3];
2991 - if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
2992 - iforce->device_memory.start, iforce->device_memory.end, 2L,
2997 - data[0] = LO(mod_chunk->start);
2998 - data[1] = HI(mod_chunk->start);
2999 - data[2] = HI(level);
3001 - send_packet(iforce, FF_CMD_MAGNITUDE, data);
3007 - * Upload the component of an effect dealing with the period, phase and magnitude
3010 -static int make_period_modifier(struct iforce* iforce, struct resource* mod_chunk,
3011 - __s16 magnitude, __s16 offset, u16 period, u16 phase)
3013 - unsigned char data[7];
3015 - period = TIME_SCALE(period);
3017 - if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
3018 - iforce->device_memory.start, iforce->device_memory.end, 2L,
3023 - data[0] = LO(mod_chunk->start);
3024 - data[1] = HI(mod_chunk->start);
3026 - data[2] = HI(magnitude);
3027 - data[3] = HI(offset);
3028 - data[4] = HI(phase);
3030 - data[5] = LO(period);
3031 - data[6] = HI(period);
3033 - send_packet(iforce, FF_CMD_PERIOD, data);
3039 - * Uploads the part of an effect setting the shape of the force
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)
3046 - unsigned char data[8];
3048 - attack_duration = TIME_SCALE(attack_duration);
3049 - fade_duration = TIME_SCALE(fade_duration);
3051 - if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
3052 - iforce->device_memory.start, iforce->device_memory.end, 2L,
3057 - data[0] = LO(mod_chunk->start);
3058 - data[1] = HI(mod_chunk->start);
3060 - data[2] = LO(attack_duration);
3061 - data[3] = HI(attack_duration);
3062 - data[4] = HI(initial_level);
3064 - data[5] = LO(fade_duration);
3065 - data[6] = HI(fade_duration);
3066 - data[7] = HI(final_level);
3068 - send_packet(iforce, FF_CMD_SHAPE, data);
3074 - * Component of spring, friction, inertia... effects
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)
3081 - unsigned char data[10];
3083 - if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
3084 - iforce->device_memory.start, iforce->device_memory.end, 2L,
3089 - data[0] = LO(mod_chunk->start);
3090 - data[1] = HI(mod_chunk->start);
3095 - data[4] = LO(center);
3096 - data[5] = HI(center);
3101 - data[8] = HI(rsat);
3102 - data[9] = HI(lsat);
3104 - send_packet(iforce, FF_CMD_INTERACT, data);
3109 -static unsigned char find_button(struct iforce *iforce, signed short button)
3112 - for (i = 1; iforce->type->btn[i] >= 0; i++)
3113 - if (iforce->type->btn[i] == button)
3119 - * Send the part common to all effects to the device
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)
3126 - unsigned char data[14];
3128 - duration = TIME_SCALE(duration);
3129 - delay = TIME_SCALE(delay);
3130 - interval = TIME_SCALE(interval);
3133 - data[1] = effect_type;
3134 - data[2] = LO(axes) | find_button(iforce, button);
3136 - data[3] = LO(duration);
3137 - data[4] = HI(duration);
3139 - data[5] = HI(direction);
3141 - data[6] = LO(interval);
3142 - data[7] = HI(interval);
3144 - data[8] = LO(mod_id1);
3145 - data[9] = HI(mod_id1);
3146 - data[10] = LO(mod_id2);
3147 - data[11] = HI(mod_id2);
3149 - data[12] = LO(delay);
3150 - data[13] = HI(delay);
3152 - send_packet(iforce, FF_CMD_EFFECT, data);
3158 - * Upload a periodic effect to the device
3161 -static int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect)
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);
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);
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);
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;
3193 - err = make_core(iforce, effect->id,
3194 - mod1_chunk->start,
3195 - mod2_chunk->start,
3198 - effect->replay.length,
3199 - effect->replay.delay,
3200 - effect->trigger.button,
3201 - effect->trigger.interval,
3202 - effect->u.periodic.direction);
3208 - * Upload a constant force effect
3210 -static int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect)
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);
3218 - printk(KERN_DEBUG "iforce.c: make constant effect\n");
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);
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);
3232 - err = make_core(iforce, effect->id,
3233 - mod1_chunk->start,
3234 - mod2_chunk->start,
3237 - effect->replay.length,
3238 - effect->replay.delay,
3239 - effect->trigger.button,
3240 - effect->trigger.interval,
3241 - effect->u.constant.direction);
3247 - * Upload an interactive effect. Those are for example friction, inertia, springs...
3249 -static int iforce_upload_interactive(struct iforce* iforce, struct ff_effect* effect)
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);
3255 - u16 mod1, mod2, direction;
3258 - printk(KERN_DEBUG "iforce.c: make interactive effect\n");
3260 - switch (effect->type) {
3261 - case FF_SPRING: type = 0x40; break;
3262 - case FF_FRICTION: type = 0x41; break;
3263 - default: return -1;
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);
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)) {
3280 - case 0: /* Only one axis, choose orientation */
3281 - mod1 = mod_chunk->start;
3283 - direction = effect->u.interactive.direction;
3287 - case 1: /* Only X axis */
3288 - mod1 = mod_chunk->start;
3290 - direction = 0x5a00;
3294 - case 2: /* Only Y axis */
3296 - mod2 = mod_chunk->start;
3297 - direction = 0xb400;
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;
3313 - err = make_core(iforce, effect->id,
3316 - effect->replay.length, effect->replay.delay,
3317 - effect->trigger.button, effect->trigger.interval,
3324 - * Function called when an ioctl is performed on the event dev entry.
3325 - * It uploads an effect to the device
3327 -static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
3329 - struct iforce* iforce = (struct iforce*)(dev->private);
3332 - printk(KERN_DEBUG "iforce.c: upload effect\n");
3338 - for (id=0; id < FF_EFFECTS_MAX; ++id)
3339 - if (!test_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
3341 - if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
3345 - set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags);
3348 - * Upload the effect
3351 - switch (effect->type) {
3354 - return iforce_upload_periodic(iforce, effect);
3357 - return iforce_upload_constant(iforce, effect);
3361 - return iforce_upload_interactive(iforce, effect);
3369 - * Erases an effect: it frees the effect id and mark as unused the memory
3370 - * allocated for the parameters
3372 -static int iforce_erase_effect(struct input_dev *dev, int effect_id)
3374 - struct iforce* iforce = (struct iforce*)(dev->private);
3376 - struct iforce_core_effect* core_effect;
3378 - printk(KERN_DEBUG "iforce.c: erase effect %d\n", effect_id);
3380 - if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
3383 - core_effect = iforce->core_effects + effect_id;
3385 - if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
3386 - err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk));
3388 - if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
3389 - err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk));
3391 - /*TODO: remember to change that if more FF_MOD* bits are added */
3392 - core_effect->flags[0] = 0;
3396 -static int iforce_init_device(struct iforce *iforce)
3398 - unsigned char c[] = "CEOV";
3401 - init_waitqueue_head(&iforce->wait);
3402 - iforce->dev.ff_effects_max = 10;
3405 - * Input device fields.
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;
3418 - * On-device memory allocation.
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;
3430 - * Wait until device ready - until it sends its first response.
3433 - for (i = 0; i < 20; i++)
3434 - if (!get_id_packet(iforce, "O"))
3437 - if (i == 20) { /* 5 seconds */
3438 - printk(KERN_ERR "iforce.c: Timeout waiting for response from device.\n");
3439 - iforce_close(&iforce->dev);
3444 - * Get device info.
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];
3457 - * Display additional info.
3460 - for (i = 0; c[i]; i++)
3461 - if (!get_id_packet(iforce, c + i))
3462 - dump_packet("info", iforce->ecmd, iforce->edata);
3465 - * Disable spring, enable force feedback.
3466 - * FIXME: We should use iforce_set_autocenter() et al here.
3469 - send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
3470 - send_packet(iforce, FF_CMD_ENABLE, "\004");
3473 - * Find appropriate device entry
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)
3481 - iforce->type = iforce_device + i;
3483 - sprintf(iforce->name, iforce->type->name,
3484 - iforce->dev.idproduct, iforce->dev.idvendor);
3487 - * Set input device bitfields and ranges.
3490 - iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF);
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);
3499 - for (i = 0; iforce->type->abs[i] >= 0; i++) {
3501 - signed short t = iforce->type->abs[i];
3502 - set_bit(t, iforce->dev.absbit);
3510 - iforce->dev.absmax[t] = 1920;
3511 - iforce->dev.absmin[t] = -1920;
3512 - iforce->dev.absflat[t] = 128;
3513 - iforce->dev.absfuzz[t] = 16;
3515 - set_bit(FF_ABS(t), iforce->dev.ffbit);
3518 - case ABS_THROTTLE:
3522 - iforce->dev.absmax[t] = 255;
3523 - iforce->dev.absmin[t] = 0;
3528 - iforce->dev.absmax[t] = 1;
3529 - iforce->dev.absmin[t] = -1;
3534 - for (i = 0; iforce->type->ff[i] >= 0; i++)
3535 - set_bit(iforce->type->ff[i], iforce->dev.ffbit);
3538 - * Register input device.
3541 - input_register_device(&iforce->dev);
3548 -static void iforce_usb_irq(struct urb *urb)
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);
3556 -static void iforce_usb_out(struct urb *urb)
3558 - struct iforce *iforce = urb->context;
3559 - if (urb->status) return;
3560 - if (waitqueue_active(&iforce->wait))
3561 - wake_up(&iforce->wait);
3564 -static void iforce_usb_ctrl(struct urb *urb)
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);
3573 -static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum,
3574 - const struct usb_device_id *id)
3576 - struct usb_endpoint_descriptor *epirq, *epout;
3577 - struct iforce *iforce;
3579 - epirq = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
3580 - epout = dev->config[0].interface[ifnum].altsetting[0].endpoint + 1;
3582 - if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) return NULL;
3583 - memset(iforce, 0, sizeof(struct iforce));
3585 - iforce->bus = IFORCE_USB;
3586 - iforce->usbdev = dev;
3588 - iforce->dr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
3589 - iforce->dr.wIndex = 0;
3590 - iforce->dr.wLength = 16;
3592 - FILL_INT_URB(&iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
3593 - iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
3595 - FILL_BULK_URB(&iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
3596 - iforce + 1, 32, iforce_usb_out, iforce);
3598 - FILL_CONTROL_URB(&iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
3599 - (void*) &iforce->dr, iforce->edata, 16, iforce_usb_ctrl, iforce);
3601 - if (iforce_init_device(iforce)) {
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);
3613 -static void iforce_usb_disconnect(struct usb_device *dev, void *ptr)
3615 - struct iforce *iforce = ptr;
3616 - usb_unlink_urb(&iforce->irq);
3617 - input_unregister_device(&iforce->dev);
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 */
3630 -MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
3632 -static struct usb_driver iforce_usb_driver = {
3634 - probe: iforce_usb_probe,
3635 - disconnect: iforce_usb_disconnect,
3636 - id_table: iforce_usb_ids,
3643 -static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
3645 - struct iforce* iforce = serio->private;
3647 - if (!iforce->pkt) {
3648 - if (data != 0x2b) {
3655 - if (!iforce->id) {
3656 - if (data > 3 && data != 0xff) {
3660 - iforce->id = data;
3664 - if (!iforce->len) {
3665 - if (data > IFORCE_MAX_LENGTH) {
3670 - iforce->len = data;
3674 - if (iforce->idx < iforce->len) {
3675 - iforce->csum += iforce->data[iforce->idx++] = data;
3679 - if (iforce->idx == iforce->len) {
3680 - iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
3689 -static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
3691 - struct iforce *iforce;
3692 - if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
3695 - if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return;
3696 - memset(iforce, 0, sizeof(struct iforce));
3698 - iforce->bus = IFORCE_232;
3699 - iforce->serio = serio;
3700 - serio->private = iforce;
3702 - if (serio_open(serio, dev)) {
3707 - if (iforce_init_device(iforce)) {
3708 - serio_close(serio);
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);
3718 -static void iforce_serio_disconnect(struct serio *serio)
3720 - struct iforce* iforce = serio->private;
3722 - input_unregister_device(&iforce->dev);
3723 - serio_close(serio);
3727 -static struct serio_dev iforce_serio_dev = {
3728 - interrupt: iforce_serio_irq,
3729 - connect: iforce_serio_connect,
3730 - disconnect: iforce_serio_disconnect,
3735 -static int __init iforce_init(void)
3738 - usb_register(&iforce_usb_driver);
3741 - serio_register_device(&iforce_serio_dev);
3746 -static void __exit iforce_exit(void)
3749 - usb_deregister(&iforce_usb_driver);
3752 - serio_unregister_device(&iforce_serio_dev);
3756 -module_init(iforce_init);
3757 -module_exit(iforce_exit);
3758 diff -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
3762 set_bit(t, interact->dev.keybit);
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);
3771 fail2: gameport_close(gameport);
3772 diff -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
3777 input_register_device(&magellan->dev);
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);
3784 diff -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
3792 - * Copyright (c) 1999-2000 Vojtech Pavlik
3794 - * Sponsored by SuSE
3795 + * Copyright (c) 1999-2001 Vojtech Pavlik
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
3807 #include <linux/stddef.h>
3808 #include <linux/module.h>
3809 #include <linux/serio.h>
3810 +#include <linux/errno.h>
3812 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
3813 +MODULE_DESCRIPTION("Serio abstraction core");
3814 MODULE_LICENSE("GPL");
3816 EXPORT_SYMBOL(serio_register_port);
3819 static struct serio *serio_list;
3820 static struct serio_dev *serio_dev;
3821 -static int serio_number;
3823 static void serio_find_dev(struct serio *serio)
3827 void serio_register_port(struct serio *serio)
3829 - serio->number = serio_number++;
3830 serio->next = serio_list;
3832 serio_find_dev(serio);
3835 if (serio->dev && serio->dev->disconnect)
3836 serio->dev->disconnect(serio);
3841 void serio_register_device(struct serio_dev *dev)
3842 diff -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
3850 * Copyright (c) 1999-2001 Vojtech Pavlik
3852 - * Sponsored by SuSE
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
3864 #include <asm/uaccess.h>
3866 #include <linux/serio.h>
3867 #include <linux/tty.h>
3869 +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
3870 +MODULE_DESCRIPTION("Input device TTY line discipline");
3871 +MODULE_LICENSE("GPL");
3874 struct tty_struct *tty;
3875 wait_queue_head_t wait;
3880 +char serport_name[] = "Serial port";
3883 * Callback functions from the serio code.
3886 static int serport_ldisc_open(struct tty_struct *tty)
3888 struct serport *serport;
3896 memset(serport, 0, sizeof(struct serport));
3898 + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
3900 tty->disc_data = serport;
3902 + strcpy(ttyname, tty->driver.name);
3903 + for (i = 0; ttyname[i] != 0 && ttyname[i] != '/'; i++);
3906 + sprintf(serport->phys, "%s%d/serio0", ttyname, MINOR(tty->device) - tty->driver.minor_start);
3908 + serport->serio.name = serport_name;
3909 + serport->serio.phys = serport->phys;
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 @@
3916 serio_register_port(&serport->serio);
3918 - printk(KERN_INFO "serio%d: Serial port %s\n", serport->serio.number, name);
3919 + printk(KERN_INFO "serio: Serial port %s\n", name);
3921 add_wait_queue(&serport->wait, &wait);
3922 - current->state = TASK_INTERRUPTIBLE;
3923 + set_current_state(TASK_INTERRUPTIBLE);
3925 while(serport->serio.type && !signal_pending(current)) schedule();
3927 - current->state = TASK_RUNNING;
3928 + set_current_state(TASK_RUNNING);
3929 remove_wait_queue(&serport->wait, &wait);
3931 serio_unregister_port(&serport->serio);
3932 @@ -187,6 +204,14 @@
3936 +static void serport_ldisc_write_wakeup(struct tty_struct * tty)
3938 + struct serport *sp = (struct serport *) tty->disc_data;
3940 + serio_dev_write_wakeup(&sp->serio);
3945 * The line discipline structure.
3948 ioctl: serport_ldisc_ioctl,
3949 receive_buf: serport_ldisc_receive,
3950 receive_room: serport_ldisc_room,
3951 + write_wakeup: serport_ldisc_write_wakeup
3957 module_init(serport_init);
3958 module_exit(serport_exit);
3960 -MODULE_LICENSE("GPL");
3961 diff -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
3965 set_bit(code, sw->dev[i].keybit);
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);
3975 diff -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
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);
3988 case 'D': /* Ball data */
3989 diff -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
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);
4002 case 'D': /* Ball + button data */
4003 diff -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
4008 input_register_device(&stinger->dev);
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);
4015 diff -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
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);
4029 diff -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
4033 tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
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);
4042 if (!tgfx->sticks) {
4043 diff -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
4048 input_register_device(&warrior->dev);
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);
4055 diff -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
4063 * Copyright (c) 1999-2001 Vojtech Pavlik
4065 * Event char devices, giving access to raw input device events.
4067 - * Sponsored by SuSE
4072 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
4081 #define EVDEV_MINOR_BASE 64
4087 struct input_handle handle;
4088 wait_queue_head_t wait;
4089 devfs_handle_t devfs;
4091 return retval < 0 ? retval : 0;
4094 +static int evdev_flush(struct file * file)
4096 + struct evdev_list *list = (struct evdev_list*)file->private_data;
4098 + if (!list->evdev->exist) return -ENODEV;
4100 + return input_flush_device(&list->evdev->handle, file);
4103 static int evdev_release(struct inode * inode, struct file * file)
4105 struct evdev_list *list = file->private_data;
4106 struct evdev_list **listptr;
4109 listptr = &list->evdev->list;
4110 evdev_fasync(-1, file, 0);
4122 @@ -122,10 +128,16 @@
4124 struct evdev_list *list;
4125 int i = MINOR(inode->i_rdev) - EVDEV_MINOR_BASE;
4128 if (i >= EVDEV_MINORS || !evdev_table[i])
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;
4136 if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
4138 memset(list, 0, sizeof(struct evdev_list));
4140 struct input_event event;
4143 + if (!list->evdev->exist) return -ENODEV;
4145 while (retval < count) {
4147 if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
4149 if (list->head == list->tail) {
4151 add_wait_queue(&list->evdev->wait, &wait);
4152 - current->state = TASK_INTERRUPTIBLE;
4153 + set_current_state(TASK_INTERRUPTIBLE);
4155 while (list->head == list->tail) {
4161 - current->state = TASK_RUNNING;
4162 + set_current_state(TASK_RUNNING);
4163 remove_wait_queue(&list->evdev->wait, &wait);
4167 struct evdev_list *list = file->private_data;
4168 struct evdev *evdev = list->evdev;
4169 struct input_dev *dev = evdev->handle.dev;
4173 + if (!evdev->exist) return -ENODEV;
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;
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;
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;
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;
4201 + if ((retval = put_user(u, ((int *) arg) + 1))) return retval;
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;
4217 if (dev->upload_effect) {
4218 @@ -282,22 +332,55 @@
4219 default: return -EINVAL;
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);
4227 + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
4228 return copy_to_user((char *) arg, bits, len) ? -EFAULT : len;
4231 + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
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;
4238 + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
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;
4245 + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
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;
4252 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
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;
4261 + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
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;
4269 + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
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;
4277 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
4279 int t = _IOC_NR(cmd) & ABS_MAX;
4280 @@ -323,9 +406,10 @@
4281 release: evdev_release,
4283 fasync: evdev_fasync,
4284 + flush: evdev_flush
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)
4290 struct evdev *evdev;
4292 @@ -344,16 +428,17 @@
4294 evdev->minor = minor;
4295 evdev_table[minor] = evdev;
4297 + sprintf(evdev->name, "event%d", minor);
4299 evdev->handle.dev = dev;
4300 + evdev->handle.name = evdev->name;
4301 evdev->handle.handler = handler;
4302 evdev->handle.private = evdev;
4306 evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
4308 -// printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number);
4311 return &evdev->handle;
4313 @@ -374,12 +459,21 @@
4317 +static struct input_device_id evdev_ids[] = {
4318 + { driver_info: 1 }, /* Matches all devices */
4319 + { }, /* Terminating zero entry */
4322 +MODULE_DEVICE_TABLE(input, evdev_ids);
4324 static struct input_handler evdev_handler = {
4326 connect: evdev_connect,
4327 disconnect: evdev_disconnect,
4329 minor: EVDEV_MINOR_BASE,
4331 + id_table: evdev_ids,
4334 static int __init evdev_init(void)
4336 module_init(evdev_init);
4337 module_exit(evdev_exit);
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");
4345 diff -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
4353 * Copyright (c) 1999-2001 Vojtech Pavlik
4355 - * The input layer module itself
4357 - * Sponsored by SuSE
4363 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
4372 #include <linux/init.h>
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>
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");
4390 EXPORT_SYMBOL(input_register_device);
4391 EXPORT_SYMBOL(input_unregister_device);
4392 EXPORT_SYMBOL(input_register_handler);
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);
4401 #define INPUT_MAJOR 13
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)];
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;
4415 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
4417 struct input_handle *handle = dev->handle;
4420 + * Wake up the device if it is sleeping.
4423 + pm_access(dev->pm_dev);
4426 * Filter non-events, and bad input values out.
4429 if (type > EV_MAX || !test_bit(type, dev->evbit))
4432 + add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
4437 @@ -187,16 +203,36 @@
4438 mod_timer(&dev->timer, jiffies + dev->rep[REP_PERIOD]);
4441 +int input_accept_process(struct input_handle *handle, struct file *file)
4443 + if (handle->dev->accept)
4444 + return handle->dev->accept(handle->dev, file);
4449 int input_open_device(struct input_handle *handle)
4451 + if (handle->dev->pm_dev)
4452 + pm_access(handle->dev->pm_dev);
4454 if (handle->dev->open)
4455 return handle->dev->open(handle->dev);
4459 +int input_flush_device(struct input_handle* handle, struct file* file)
4461 + if (handle->dev->flush)
4462 + return handle->dev->flush(handle->dev, file);
4467 void input_close_device(struct input_handle *handle)
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);
4474 @@ -210,25 +246,197 @@
4475 handle->handler->handle = handle;
4479 + * input_find_and_remove - Find and remove node
4481 + * @type: data type
4482 + * @initval: initial value
4483 + * @targ: node to find
4484 + * @next: next node in the list
4486 + * Searches the linked list for the target node @targ. If the node
4487 + * is found, it is removed from the list.
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.
4492 + * Returns nothing.
4494 +#define input_find_and_remove(type, initval, targ, next) \
4497 + for (ptr = &initval; *ptr; ptr = &((*ptr)->next)) \
4498 + if (*ptr == targ) break; \
4499 + if (*ptr) *ptr = (*ptr)->next; \
4502 static void input_unlink_handle(struct input_handle *handle)
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);
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]) \
4513 + if (i != NBITS(max)) \
4516 +static struct input_device_id *input_match_device(struct input_device_id *id, struct input_dev *dev)
4520 + for (; id->flags || id->driver_info; id++) {
4522 + if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
4523 + if (id->idbus != dev->idbus)
4526 - handleptr = &handle->dev->handle;
4527 - while (*handleptr && (*handleptr != handle))
4528 - handleptr = &((*handleptr)->dnext);
4529 - *handleptr = (*handleptr)->dnext;
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)
4539 + if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
4540 + if (id->idproduct != dev->idproduct)
4543 + if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
4544 + if (id->idversion != dev->idversion)
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);
4563 + * Input hotplugging interface - loading event handlers based on
4564 + * device bitfields.
4567 +#ifdef CONFIG_HOTPLUG
4570 + * Input hotplugging invokes what /proc/sys/kernel/hotplug says
4571 + * (normally /sbin/hotplug) when input devices get added or removed.
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.
4579 +#define SPRINTF_BIT_A(bit, name, max) \
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]); \
4590 +#define SPRINTF_BIT_A2(bit, name, max, ev) \
4592 + if (test_bit(ev, dev->evbit)) \
4593 + SPRINTF_BIT_A(bit, name, max); \
4596 +static void input_call_hotplug(char *verb, struct input_dev *dev)
4598 + char *argv[3], **envp, *buf, *scratch;
4599 + int i = 0, j, value;
4601 + if (!hotplug_path[0]) {
4602 + printk(KERN_ERR "input.c: calling hotplug a hotplug agent defined\n");
4605 + if (in_interrupt()) {
4606 + printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
4609 + if (!current->fs->root) {
4610 + printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
4613 + if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
4614 + printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
4617 + if (!(buf = kmalloc(1024, GFP_KERNEL))) {
4619 + printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
4623 + argv[0] = hotplug_path;
4624 + argv[1] = "input";
4627 + envp[i++] = "HOME=/";
4628 + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
4632 + envp[i++] = scratch;
4633 + scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
4635 + envp[i++] = scratch;
4636 + scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
4637 + dev->idbus, dev->idvendor, dev->idproduct, dev->idversion) + 1;
4640 + envp[i++] = scratch;
4641 + scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
4645 + envp[i++] = scratch;
4646 + scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
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);
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]);
4663 + value = call_usermodehelper(argv [0], argv, envp);
4669 + printk(KERN_WARNING "input.c: hotplug returned %d\n", value);
4674 void input_register_device(struct input_dev *dev)
4676 struct input_handler *handler = input_handler;
4677 struct input_handle *handle;
4678 + struct input_device_id *id;
4681 * Initialize repeat timer to default values.
4682 @@ -244,35 +452,70 @@
4686 - if (input_number >= INPUT_DEVICES) {
4687 - printk(KERN_WARNING "input: ran out of input device numbers!\n");
4688 - dev->number = input_number;
4690 - dev->number = find_first_zero_bit(input_devices, INPUT_DEVICES);
4691 - set_bit(dev->number, input_devices);
4694 dev->next = input_dev;
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;
4712 + * Notify the hotplug agent.
4715 +#ifdef CONFIG_HOTPLUG
4716 + input_call_hotplug("add", dev);
4723 +#ifdef CONFIG_PROC_FS
4724 + input_devices_state++;
4725 + wake_up(&input_devices_poll_wait);
4729 +#define DUMP_ARRAY(n, array) \
4730 +printk(KERN_DEBUG " ");\
4731 +for (i=0; i<NBITS(n); ++i)\
4732 + printk("%0X ", array[i]);\
4735 +void dump_id_table(struct input_device_id* id)
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);
4743 + if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) {
4744 + DUMP_ARRAY(NBITS(KEY_MAX), id->keybit);
4748 void input_unregister_device(struct input_dev *dev)
4750 struct input_handle *handle = dev->handle;
4751 - struct input_dev **devptr = &input_dev;
4752 struct input_handle *dnext;
4757 + * Turn off power management for the device.
4760 + pm_unregister(dev->pm_dev);
4763 * Kill any pending repeat timers.
4765 @@ -291,23 +534,35 @@
4769 - * Remove the device.
4770 + * Notify the hotplug agent.
4773 - while (*devptr && (*devptr != dev))
4774 - devptr = &((*devptr)->next);
4775 - *devptr = (*devptr)->next;
4776 +#ifdef CONFIG_HOTPLUG
4777 + input_call_hotplug("remove", dev);
4781 + * Remove the device.
4783 + input_find_and_remove(struct input_dev, input_dev, dev, next);
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);
4798 void input_register_handler(struct input_handler *handler)
4800 struct input_dev *dev = input_dev;
4801 struct input_handle *handle;
4802 + struct input_device_id *id;
4804 + if (!handler) return;
4807 * Add minors if needed.
4808 @@ -326,17 +581,27 @@
4810 * Notify it about all existing devices.
4812 +// dump_id_table(handler->id_table);
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);
4827 +#ifdef CONFIG_PROC_FS
4828 + input_devices_state++;
4829 + wake_up(&input_devices_poll_wait);
4833 void input_unregister_handler(struct input_handler *handler)
4835 - struct input_handler **handlerptr = &input_handler;
4836 struct input_handle *handle = handler->handle;
4837 struct input_handle *hnext;
4839 @@ -354,18 +619,23 @@
4844 - while (*handlerptr && (*handlerptr != handler))
4845 - handlerptr = &((*handlerptr)->next);
4847 - *handlerptr = (*handlerptr)->next;
4848 + input_find_and_remove(struct input_handler, input_handler, handler,
4855 if (handler->fops != NULL)
4856 input_table[handler->minor >> 5] = NULL;
4862 +#ifdef CONFIG_PROC_FS
4863 + input_devices_state++;
4864 + wake_up(&input_devices_poll_wait);
4868 static int input_open_file(struct inode *inode, struct file *file)
4870 old_fops = file->f_op;
4871 file->f_op = new_fops;
4874 err = new_fops->open(inode, file);
4878 fops_put(file->f_op);
4879 @@ -419,18 +687,164 @@
4880 devfs_unregister(handle);
4884 + * ProcFS interface for the input drivers.
4887 +#ifdef CONFIG_PROC_FS
4889 +#define SPRINTF_BIT_B(bit, name, max) \
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"); \
4899 +#define SPRINTF_BIT_B2(bit, name, max, ev) \
4901 + if (test_bit(ev, dev->evbit)) \
4902 + SPRINTF_BIT_B(bit, name, max); \
4906 +static unsigned int input_devices_poll(struct file *file, poll_table *wait)
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;
4915 +static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
4917 + struct input_dev *dev = input_dev;
4918 + struct input_handle *handle;
4921 + int i, len, cnt = 0;
4925 + len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
4926 + dev->idbus, dev->idvendor, dev->idproduct, dev->idversion);
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=");
4932 + handle = dev->handle;
4935 + len += sprintf(buf + len, "%s ", handle->name);
4936 + handle = handle->dnext;
4939 + len += sprintf(buf + len, "\n");
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);
4950 + len += sprintf(buf + len, "\n");
4956 + *start = buf + (pos - (at - len));
4958 + } else cnt += len;
4967 + if (!dev) *eof = 1;
4969 + return (count > cnt) ? cnt : count;
4972 +static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
4974 + struct input_handler *handler = input_handler;
4977 + int len = 0, cnt = 0;
4982 + if (handler->fops)
4983 + len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n",
4984 + i++, handler->name, handler->minor);
4986 + len = sprintf(buf, "N: Number=%d Name=%s\n",
4987 + i++, handler->name);
4993 + *start = buf + (pos - (at - len));
4995 + } else cnt += len;
5001 + handler = handler->next;
5004 + if (!handler) *eof = 1;
5006 + return (count > cnt) ? cnt : count;
5011 static int __init input_init(void)
5013 + struct proc_dir_entry *entry;
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;
5024 if (devfs_register_chrdev(INPUT_MAJOR, "input", &input_fops)) {
5025 printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
5029 input_devfs_handle = devfs_mk_dir(NULL, "input", NULL);
5034 static void __exit input_exit(void)
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);
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);
5044 diff -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
5052 - * Copyright (c) 1999-2000 Vojtech Pavlik
5053 + * Copyright (c) 1999-2001 Vojtech Pavlik
5054 * Copyright (c) 1999 Colin Van Dyke
5056 * Joystick device driver for the input driver suite.
5058 - * Sponsored by SuSE and Intel
5063 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
5074 #include <linux/init.h>
5075 #include <linux/smp_lock.h>
5077 +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
5078 +MODULE_DESCRIPTION("Joystick device interfaces");
5079 +MODULE_SUPPORTED_DEVICE("input/js");
5080 +MODULE_LICENSE("GPL");
5082 #define JOYDEV_MINOR_BASE 0
5083 #define JOYDEV_MINORS 32
5084 #define JOYDEV_BUFFER_SIZE 64
5090 struct input_handle handle;
5091 wait_queue_head_t wait;
5092 devfs_handle_t devfs;
5095 static struct joydev *joydev_table[JOYDEV_MINORS];
5097 -MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
5098 -MODULE_DESCRIPTION("Joystick device driver");
5099 -MODULE_LICENSE("GPL");
5100 -MODULE_SUPPORTED_DEVICE("input/js");
5102 static int joydev_correct(int value, struct js_corr *corr)
5104 switch (corr->type) {
5106 struct joydev_list *list = file->private_data;
5107 struct joydev_list **listptr;
5110 listptr = &list->joydev->list;
5111 joydev_fasync(-1, file, 0);
5121 @@ -254,10 +251,15 @@
5122 if (list->head == list->tail && list->startup == joydev->nabs + joydev->nkey) {
5124 add_wait_queue(&list->joydev->wait, &wait);
5125 - current->state = TASK_INTERRUPTIBLE;
5126 + set_current_state(TASK_INTERRUPTIBLE);
5128 while (list->head == list->tail) {
5130 + if (!joydev->exist) {
5135 if (file->f_flags & O_NONBLOCK) {
5142 - current->state = TASK_RUNNING;
5143 + set_current_state(TASK_RUNNING);
5144 remove_wait_queue(&list->joydev->wait, &wait);
5148 struct input_dev *dev = joydev->handle.dev;
5151 + if (!joydev->exist) return -ENODEV;
5156 @@ -410,16 +414,11 @@
5157 fasync: joydev_fasync,
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)
5163 struct joydev *joydev;
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;
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;
5178 + sprintf(joydev->name, "js%d", minor);
5180 joydev->handle.dev = dev;
5181 + joydev->handle.name = joydev->name;
5182 joydev->handle.handler = handler;
5183 joydev->handle.private = joydev;
5185 - joydev->exist = 1;
5187 for (i = 0; i < ABS_MAX; i++)
5188 if (test_bit(i, dev->absbit)) {
5189 joydev->absmap[i] = joydev->nabs;
5192 // printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number);
5194 + joydev->exist = 1;
5196 return &joydev->handle;
5199 @@ -502,12 +504,35 @@
5203 +static struct input_device_id joydev_ids[] = {
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) },
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) },
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) },
5219 + { }, /* Terminating entry */
5222 +MODULE_DEVICE_TABLE(input, joydev_ids);
5224 static struct input_handler joydev_handler = {
5225 event: joydev_event,
5226 connect: joydev_connect,
5227 disconnect: joydev_disconnect,
5229 minor: JOYDEV_MINOR_BASE,
5231 + id_table: joydev_ids,
5234 static int __init joydev_init(void)
5235 diff -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);
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)
5245 struct input_handle *handle;
5248 - if (!test_bit(EV_KEY, dev->evbit))
5251 - for (i = KEY_RESERVED; i < BTN_MISC; i++)
5252 - if (test_bit(i, dev->keybit)) break;
5254 - if (i == BTN_MISC)
5257 if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
5259 memset(handle, 0, sizeof(struct input_handle));
5260 @@ -212,10 +203,25 @@
5264 +static struct input_device_id keybdev_ids[] = {
5265 + /* If it's got an "esc" key, it's a keyboard */
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) },
5272 + { }, /* Terminating entry */
5275 +MODULE_DEVICE_TABLE(input, keybdev_ids);
5277 static struct input_handler keybdev_handler = {
5278 event: keybdev_event,
5279 connect: keybdev_connect,
5280 disconnect: keybdev_disconnect,
5282 + id_table: keybdev_ids,
5285 static int __init keybdev_init(void)
5286 diff -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
5294 - * Copyright (c) 1999-2000 Vojtech Pavlik
5295 + * Copyright (c) 1999-2001 Vojtech Pavlik
5297 - * Input driver to ImExPS/2 device driver module.
5299 - * Sponsored by SuSE
5300 + * Input driver to ExplorerPS/2 device driver module.
5305 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
5314 #define MOUSEDEV_MINOR_BASE 32
5316 #include <linux/smp_lock.h>
5317 #include <linux/random.h>
5319 +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
5320 +MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
5321 +MODULE_LICENSE("GPL");
5323 #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
5324 #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
5331 wait_queue_head_t wait;
5332 struct mousedev_list *list;
5333 struct input_handle handle;
5335 struct mousedev_list *list;
5338 - add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
5341 list = (*mousedev)->list;
5343 @@ -101,13 +102,23 @@
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;
5350 + list->dx += (value * xres - list->oldx) / size;
5351 + list->oldx += list->dx * size;
5353 + list->dx += value - list->oldx;
5354 + list->oldx += list->dx;
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;
5362 + list->dy -= (value * yres - list->oldy) / size;
5363 + list->oldy -= list->dy * size;
5365 + list->dy -= value - list->oldy;
5366 + list->oldy -= list->dy;
5372 struct mousedev_list *list = file->private_data;
5373 struct mousedev_list **listptr;
5376 listptr = &list->mousedev->list;
5377 mousedev_fasync(-1, file, 0);
5387 @@ -216,7 +225,14 @@
5388 static int mousedev_open(struct inode * inode, struct file * file)
5390 struct mousedev_list *list;
5391 - int i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE;
5394 +#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5395 + if (major(inode->i_rdev) == MISC_MAJOR))
5399 + i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE;
5401 if (i >= MOUSEDEV_MINORS || !mousedev_table[i])
5404 if (!list->ready && !list->buffer) {
5406 add_wait_queue(&list->mousedev->wait, &wait);
5407 - current->state = TASK_INTERRUPTIBLE;
5408 + set_current_state(TASK_INTERRUPTIBLE);
5410 while (!list->ready) {
5416 - current->state = TASK_RUNNING;
5417 + set_current_state(TASK_RUNNING);
5418 remove_wait_queue(&list->mousedev->wait, &wait);
5421 @@ -403,19 +419,11 @@
5422 fasync: mousedev_fasync,
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)
5428 struct mousedev *mousedev;
5431 - if (!test_bit(EV_KEY, dev->evbit) ||
5432 - (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit)))
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)))
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);
5446 - mousedev->exist = 1;
5447 mousedev->minor = minor;
5448 mousedev_table[minor] = mousedev;
5449 + sprintf(mousedev->name, "mouse%d", minor);
5451 mousedev->handle.dev = dev;
5452 + mousedev->handle.name = mousedev->name;
5453 mousedev->handle.handler = handler;
5454 mousedev->handle.private = mousedev;
5457 if (mousedev_mix.open)
5458 input_open_device(&mousedev->handle);
5460 -// printk(KERN_INFO "mouse%d: PS/2 mouse device for input%d\n", minor, dev->number);
5461 + mousedev->exist = 1;
5463 return &mousedev->handle;
5465 @@ -461,6 +470,26 @@
5470 +static struct input_device_id mousedev_ids[] = {
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 */
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 */
5485 + { }, /* Terminating entry */
5488 +MODULE_DEVICE_TABLE(input, mousedev_ids);
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,
5497 + id_table: mousedev_ids,
5500 +#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5501 +static struct miscdevice psaux_mouse = {
5502 + PSMOUSE_MINOR, "psaux", &mousedev_fops
5506 static int __init mousedev_init(void)
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)
5516 printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");
5518 @@ -488,16 +528,15 @@
5520 static void __exit mousedev_exit(void)
5522 +#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
5523 + misc_deregister(&psaux_mouse)
5525 input_unregister_minor(mousedev_mix.devfs);
5526 input_unregister_handler(&mousedev_handler);
5529 module_init(mousedev_init);
5530 module_exit(mousedev_exit);
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");
5536 MODULE_PARM(xres, "i");
5537 MODULE_PARM_DESC(xres, "Horizontal screen resolution");
5538 diff -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
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
5550 diff -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
5554 hid-objs += hid-input.o
5557 +ifeq ($(CONFIG_HID_FF),y)
5558 + hid-objs += hid-ff.o
5561 +ifeq ($(CONFIG_LOGITECH_FF),y)
5562 + hid-objs += hid-lgff.o
5565 # Object file lists.
5568 diff -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
5572 +#ifndef _FIXP_ARITH_H
5573 +#define _FIXP_ARITH_H
5578 + * Simplistic fixed-point arithmetics.
5579 + * Hmm, I'm probably duplicating some code :(
5581 + * Copyright (c) 2002 Johann Deneux
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.
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.
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
5599 + * Should you need to contact me, the author, you can do so by
5600 + * e-mail - mail your message to <deneux@ifrance.com>
5603 +#include <linux/types.h>
5605 +// The type representing fixed-point values
5606 +typedef s16 fixp_t;
5609 +#define FRAC_MASK ((1<<FRAC_N)-1)
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
5622 +/* a: 123 -> 123.0 */
5623 +inline fixp_t fixp_new(s16 a)
5628 +/* a: 0xFFFF -> -1.0
5632 +inline fixp_t fixp_new16(s16 a)
5634 + return ((s32)a)>>(16-FRAC_N);
5637 +inline int fixp_toint(fixp_t x)
5642 +inline fixp_t fixp_cos(unsigned int degrees)
5644 + int quadrant = (degrees / 90) & 3;
5645 + unsigned int i = degrees % 90;
5647 + if (quadrant == 1 || quadrant == 3) {
5653 + return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
5656 +inline fixp_t fixp_sin(unsigned int degrees)
5658 + return -fixp_cos(degrees + 90);
5661 +inline fixp_t fixp_mult(fixp_t a, fixp_t b)
5663 + return ((s32)(a*b))>>FRAC_N;
5666 +inline fixp_t fixp_div(fixp_t a, fixp_t b)
5668 + return (a/b)<<FRAC_N;
5672 diff -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
5680 * Copyright (c) 1999 Andreas Gal
5681 * Copyright (c) 2000-2001 Vojtech Pavlik
5683 * USB HID support for Linux
5685 - * Sponsored by SuSE
5690 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
5699 #include <linux/module.h>
5701 #include <linux/usb.h>
5704 +#ifdef CONFIG_USB_HIDDEV
5705 #include <linux/hiddev.h>
5710 * Version Information
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"
5721 static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
5722 "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
5724 dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
5728 usages = parser->local.usage_index;
5730 offset = report->size;
5734 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
5735 - parser->global.unit_exponent = item_udata(item);
5736 + parser->global.unit_exponent = item_sdata(item);
5739 case HID_GLOBAL_ITEM_TAG_UNIT:
5742 for (n = 0; n < report->maxfield; n++)
5743 kfree(report->field[n]);
5745 - kfree(report->data);
5749 @@ -520,6 +519,10 @@
5753 +#ifdef CONFIG_HID_FF
5754 + hid_ff_exit(device);
5757 for (i = 0; i < HID_REPORT_TYPES; i++) {
5758 struct hid_report_enum *report_enum = device->report_enum + i;
5760 @@ -537,60 +540,64 @@
5761 * items, though they are not used yet.
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)
5767 - if ((end - start) > 0) {
5770 - __u8 b = *start++;
5771 - item->type = (b >> 2) & 3;
5772 - item->tag = (b >> 4) & 15;
5773 + if ((end - start) <= 0)
5776 - if (item->tag == HID_ITEM_TAG_LONG) {
5779 - item->format = HID_ITEM_FORMAT_LONG;
5780 + item->type = (b >> 2) & 3;
5781 + item->tag = (b >> 4) & 15;
5783 - if ((end - start) >= 2) {
5784 + if (item->tag == HID_ITEM_TAG_LONG) {
5786 - item->size = *start++;
5787 - item->tag = *start++;
5788 + item->format = HID_ITEM_FORMAT_LONG;
5790 - if ((end - start) >= item->size) {
5791 - item->data.longdata = start;
5792 - start += item->size;
5797 + if ((end - start) < 2)
5800 - item->format = HID_ITEM_FORMAT_SHORT;
5801 - item->size = b & 3;
5802 - switch (item->size) {
5808 - if ((end - start) >= 1) {
5809 - item->data.u8 = *start++;
5815 - if ((end - start) >= 2) {
5816 - item->data.u16 = le16_to_cpu( get_unaligned(((__u16*)start)++));
5822 - if ((end - start) >= 4) {
5823 - item->data.u32 = le32_to_cpu( get_unaligned(((__u32*)start)++));
5828 + item->size = *start++;
5829 + item->tag = *start++;
5831 + if ((end - start) < item->size)
5834 + item->data.longdata = start;
5835 + start += item->size;
5839 + item->format = HID_ITEM_FORMAT_SHORT;
5840 + item->size = b & 3;
5842 + switch (item->size) {
5848 + if ((end - start) < 1)
5850 + item->data.u8 = *start++;
5854 + if ((end - start) < 2)
5856 + item->data.u16 = le16_to_cpu(get_unaligned(((__u16*)start)++));
5861 + if ((end - start) < 4)
5863 + item->data.u32 = le32_to_cpu(get_unaligned(((__u32*)start)++));
5870 @@ -637,12 +644,14 @@
5873 while ((start = fetch_item(start, end, &item)) != 0) {
5875 if (item.format != HID_ITEM_FORMAT_SHORT) {
5876 dbg("unexpected long global item");
5877 hid_free_device(device);
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);
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));
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)
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;
5927 @@ -815,95 +840,46 @@
5931 - if (!(report = report_enum->report_id_hash[n])) {
5932 - dbg("undefined report_id %d received", n);
5934 - printk(KERN_DEBUG __FILE__ ": report (size %u) = ", len);
5935 - for (n = 0; n < len; n++)
5936 - printk(" %02x", data[n]);
5941 + printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len);
5942 + for (i = 0; i < n; i++)
5943 + printk(" %02x", data[i]);
5948 + if (!(report = report_enum->report_id_hash[n])) {
5949 + dbg("undefined report_id %d received", n);
5953 size = ((report->size - 1) >> 3) + 1;
5958 - dbg("report %d is too short, (%d < %d)", report->id, len, size);
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.
5969 - if (!report->data)
5970 - if (!(report->data = kmalloc(size, GFP_ATOMIC))) {
5971 - dbg("couldn't allocate report buffer");
5975 - if (report->idx + len > size) {
5976 - dbg("report data buffer overflow");
5981 - memcpy(report->data + report->idx, data, len);
5982 - report->idx += len;
5984 - if (report->idx < size)
5987 - data = report->data;
5988 + dbg("report %d is too short, (%d < %d)", report->id, len, size);
5992 for (n = 0; n < report->maxfield; n++)
5993 hid_input_field(hid, report->field[n], data);
6000 - * Interrupt input handler.
6001 + * Input interrupt completion handler.
6004 -static void hid_irq(struct urb *urb)
6005 +static void hid_irq_in(struct urb *urb)
6008 - dbg("nonzero status in irq %d", urb->status);
6009 + dbg("nonzero status in input irq %d", urb->status);
6013 - hid_input_report(HID_INPUT_REPORT, urb->transfer_buffer, urb->actual_length, urb->context);
6017 - * hid_read_report() reads in report values without waiting for an irq urb.
6020 -void hid_read_report(struct hid_device *hid, struct hid_report *report)
6022 - int len = ((report->size - 1) >> 3) + 1 + hid->report_enum[report->type].numbered;
6026 - if (hid->quirks & HID_QUIRK_NOGET)
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);
6034 - hid_input_report(report->type, data, len, hid);
6035 + hid_input_report(HID_INPUT_REPORT, urb);
6040 hid_dump_input(field->usage + offset, value);
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);
6048 if (field->logical_minimum < 0) {
6049 @@ -958,11 +935,6 @@
6053 - if ( (value > field->logical_maximum)
6054 - || (value < field->logical_minimum)) {
6055 - dbg("value %d is invalid", value);
6058 field->value[offset] = value;
6061 @@ -986,14 +958,54 @@
6066 + * Find a report with a specified HID usage.
6069 +int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type)
6071 + struct hid_report_enum *report_enum = hid->report_enum + type;
6072 + struct list_head *list = report_enum->report_list.next;
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)
6088 +int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field)
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)
6102 static int hid_submit_out(struct hid_device *hid)
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;
6110 - if (usb_submit_urb(&hid->urbout)) {
6111 + report = hid->out[hid->outtail];
6113 + hid_output_report(report, hid->outbuf);
6114 + hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1;
6115 + hid->urbout->dev = hid->dev;
6117 + if (usb_submit_urb(hid->urbout)) {
6118 err("usb_submit_urb(out) failed");
6121 @@ -1001,33 +1013,168 @@
6125 +static int hid_submit_ctrl(struct hid_device *hid)
6127 + struct hid_report *report;
6128 + unsigned char dir;
6130 + report = hid->ctrl[hid->ctrltail].report;
6131 + dir = hid->ctrl[hid->ctrltail].dir;
6133 + if (dir == USB_DIR_OUT)
6134 + hid_output_report(report, hid->ctrlbuf);
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;
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);
6146 + if (usb_submit_urb(hid->urbctrl)) {
6147 + err("usb_submit_urb(ctrl) failed");
6155 + * Output interrupt completion handler.
6158 +static void hid_irq_out(struct urb *urb)
6160 + struct hid_device *hid = urb->context;
6161 + unsigned long flags;
6164 + warn("output irq status %d received", urb->status);
6166 + spin_lock_irqsave(&hid->outlock, flags);
6168 + hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
6170 + if (hid->outhead != hid->outtail) {
6171 + hid_submit_out(hid);
6172 + spin_unlock_irqrestore(&hid->outlock, flags);
6176 + clear_bit(HID_OUT_RUNNING, &hid->iofl);
6178 + spin_unlock_irqrestore(&hid->outlock, flags);
6180 + wake_up(&hid->wait);
6184 + * Control pipe completion handler.
6187 static void hid_ctrl(struct urb *urb)
6189 struct hid_device *hid = urb->context;
6190 + unsigned long flags;
6193 warn("ctrl urb status %d received", urb->status);
6195 - hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6196 + spin_lock_irqsave(&hid->ctrllock, flags);
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);
6203 + hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6205 + if (hid->ctrlhead != hid->ctrltail) {
6206 + hid_submit_ctrl(hid);
6207 + spin_unlock_irqrestore(&hid->ctrllock, flags);
6211 + clear_bit(HID_CTRL_RUNNING, &hid->iofl);
6213 + spin_unlock_irqrestore(&hid->ctrllock, flags);
6215 + wake_up(&hid->wait);
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)
6221 - hid_output_report(report, hid->out[hid->outhead].buffer);
6223 + unsigned long flags;
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) {
6229 - hid->outhead = (hid->outhead + 1) & (HID_CONTROL_FIFO_SIZE - 1);
6230 + spin_lock_irqsave(&hid->outlock, flags);
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");
6240 - if (hid->urbout.status != -EINPROGRESS)
6241 - hid_submit_out(hid);
6242 + hid->out[hid->outhead] = report;
6243 + hid->outhead = head;
6245 + if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl))
6246 + hid_submit_out(hid);
6248 + spin_unlock_irqrestore(&hid->outlock, flags);
6252 + spin_lock_irqsave(&hid->ctrllock, flags);
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");
6260 + hid->ctrl[hid->ctrlhead].report = report;
6261 + hid->ctrl[hid->ctrlhead].dir = dir;
6262 + hid->ctrlhead = head;
6264 + if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl))
6265 + hid_submit_ctrl(hid);
6267 + spin_unlock_irqrestore(&hid->ctrllock, flags);
6270 +int hid_wait_io(struct hid_device *hid)
6272 + DECLARE_WAITQUEUE(wait, current);
6273 + int timeout = 10*HZ;
6275 + set_current_state(TASK_UNINTERRUPTIBLE);
6276 + add_wait_queue(&hid->wait, &wait);
6278 + while (timeout && (test_bit(HID_CTRL_RUNNING, &hid->iofl) ||
6279 + test_bit(HID_OUT_RUNNING, &hid->iofl)))
6280 + timeout = schedule_timeout(timeout);
6282 + set_current_state(TASK_RUNNING);
6283 + remove_wait_queue(&hid->wait, &wait);
6286 + dbg("timeout waiting for ctrl or out queue to clear");
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)
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);
6301 int hid_open(struct hid_device *hid)
6302 @@ -1035,9 +1182,9 @@
6306 - hid->urb.dev = hid->dev;
6307 + hid->urbin->dev = hid->dev;
6309 - if (usb_submit_urb(&hid->urb))
6310 + if (usb_submit_urb(hid->urbin))
6314 @@ -1046,81 +1193,83 @@
6315 void hid_close(struct hid_device *hid)
6318 - usb_unlink_urb(&hid->urb);
6319 + usb_unlink_urb(hid->urbin);
6323 - * Initialize all readable reports
6324 + * Initialize all reports
6326 +#define USB_CTRL_SET_TIMEOUT 5
6327 void hid_init_reports(struct hid_device *hid)
6330 - struct hid_report *report;
6331 struct hid_report_enum *report_enum;
6332 + struct hid_report *report;
6333 struct list_head *list;
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;
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;
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;
6365 + while ((ret = hid_wait_io(hid))) {
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);
6374 + warn("timeout initializing reports\n");
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;
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
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
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
6409 struct hid_blacklist {
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 },
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;
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;
6466 - if (quirks & HID_QUIRK_IGNORE)
6468 + (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL;
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");
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);
6483 if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
6484 @@ -1156,118 +1302,158 @@
6489 - __u8 rdesc[rsize];
6490 + if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
6491 + dbg("couldn't allocate rdesc memory");
6495 - if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) {
6496 - dbg("reading report descriptor failed");
6499 + if ((n = hid_get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
6500 + dbg("reading report descriptor failed");
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]);
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]);
6516 - if (!(hid = hid_parse_report(rdesc, rsize))) {
6517 - dbg("parsing report descriptor failed");
6520 + if (!(hid = hid_parse_report(rdesc, rsize))) {
6521 + dbg("parsing report descriptor failed");
6526 - hid->quirks = quirks;
6529 for (n = 0; n < interface->bNumEndpoints; n++) {
6531 struct usb_endpoint_descriptor *endpoint = &interface->endpoint[n];
6535 if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */
6538 - if (!(endpoint->bEndpointAddress & 0x80)) /* Not an input endpoint */
6541 - pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
6542 - maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
6544 - FILL_INT_URB(&hid->urb, dev, pipe, hid->buffer, maxp > 32 ? 32 : maxp, hid_irq, hid, endpoint->bInterval);
6547 + if (endpoint->bEndpointAddress & USB_DIR_IN) {
6550 + if (!(hid->urbin = usb_alloc_urb(0)))
6552 + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
6553 + FILL_INT_URB(hid->urbin, dev, pipe, hid->inbuf, 0, hid_irq_in, hid, endpoint->bInterval);
6557 + if (!(hid->urbout = usb_alloc_urb(0)))
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;
6565 - if (n == interface->bNumEndpoints) {
6566 - dbg("couldn't find an input interrupt endpoint");
6567 - hid_free_device(hid);
6569 + if (!hid->urbin) {
6570 + err("couldn't find an input interrupt endpoint");
6574 + init_waitqueue_head(&hid->wait);
6576 + hid->outlock = SPIN_LOCK_UNLOCKED;
6577 + hid->ctrllock = SPIN_LOCK_UNLOCKED;
6579 hid->version = hdesc->bcdHID;
6580 hid->country = hdesc->bCountryCode;
6582 hid->ifnum = interface->bInterfaceNumber;
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);
6592 - if (!(buf = kmalloc(63, GFP_KERNEL)))
6594 + if (!(buf = kmalloc(64, GFP_KERNEL)))
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);
6604 sprintf(hid->name, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
6607 + usb_make_path(dev, buf, 63);
6608 + sprintf(hid->phys, "%s/input%d", buf, ifnum);
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)
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.
6622 - if (interface->bInterfaceSubClass == 1)
6623 - usb_set_protocol(dev, hid->ifnum, 1);
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;
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);
6640 static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
6641 const struct usb_device_id *id)
6643 struct hid_device *hid;
6648 dbg("HID probe called for ifnum %d", ifnum);
6650 - if (!(hid = usb_hid_configure(dev, ifnum)))
6651 + if (!(hid = usb_hid_configure(dev, ifnum))) {
6652 + err("usb_hid_configure failed");
6656 hid_init_reports(hid);
6657 hid_dump_device(hid);
6659 +#ifdef CONFIG_HID_FF
6660 + switch (hid_ff_init(hid)) {
6665 + info("No force feedback support for this hid device");
6669 + err("hid_ff_init failed");
6670 + hid_free_device(hid);
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;
6682 + if (!hid->claimed) {
6683 + hid_free_device(hid);
6689 if (hid->claimed & HID_CLAIMED_INPUT)
6690 - printk("input%d", hid->input.number);
6692 if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV))
6694 if (hid->claimed & HID_CLAIMED_HIDDEV)
6695 @@ -1280,9 +1466,10 @@
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);
6704 + printk(": USB HID v%x.%02x %s [%s] on %s\n",
6705 + hid->version >> 8, hid->version & 0xff, c, hid->name, path);
6709 @@ -1291,12 +1478,22 @@
6711 struct hid_device *hid = ptr;
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);
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);
6726 + usb_free_urb(hid->urbin);
6727 + usb_free_urb(hid->urbctrl);
6729 + usb_free_urb(hid->urbout);
6731 hid_free_device(hid);
6734 @@ -1317,23 +1514,26 @@
6736 static int __init hid_init(void)
6738 +#ifdef CONFIG_USB_HIDDEV
6741 usb_register(&hid_driver);
6742 - info(DRIVER_VERSION " " DRIVER_AUTHOR);
6743 - info(DRIVER_DESC);
6744 + info(DRIVER_VERSION ":" DRIVER_DESC);
6749 static void __exit hid_exit(void)
6751 +#ifdef CONFIG_USB_HIDDEV
6754 usb_deregister(&hid_driver);
6757 module_init(hid_init);
6758 module_exit(hid_exit);
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);
6766 diff -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
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>
6778 * Some debug stuff for the HID parser.
6780 - * Sponsored by SuSE
6785 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
6794 struct hid_usage_entry {
6798 static struct hid_usage_entry hid_usage_table[] = {
6799 + { 0, 0, "Undefined" },
6800 { 1, 0, "GenericDesktop" },
6801 {0, 0x01, "Pointer"},
6804 { 7, 0, "Keyboard" },
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"},
6924 @@ -176,7 +282,50 @@
6925 tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
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" }
6940 + __u32 data = field->unit;
6942 + /* First nibble tells us which system we're in. */
6947 + tab(n); printk("Unit(Invalid)\n");
6950 + int earlier_unit = 0;
6952 + tab(n); printk("Unit(%s : ", systems[sys]);
6954 + for (i=1 ; i<sizeof(__u32)*2 ; i++) {
6955 + char nibble = data & 0xf;
6957 + if (nibble != 0) {
6958 + if(earlier_unit++ > 0)
6960 + printk("%s", units[sys][i]);
6962 + /* This is a _signed_ nibble(!) */
6964 + int val = nibble & 0x7;
6966 + val = -((0x7 & ~val) +1);
6967 + printk("^%d", val);
6974 tab(n); printk("Report Size(%u)\n", field->report_size);
6975 tab(n); printk("Report Count(%u)\n", field->report_count);
6976 diff -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
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.
6985 + * Copyright (c) 2002 Johann Deneux
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.
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.
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
7003 + * Should you need to contact me, the author, you can do so by
7004 + * e-mail - mail your message to <deneux@ifrance.com>
7007 +#include <linux/input.h>
7010 +#include <linux/usb.h>
7014 +/* Drivers' initializing functions */
7015 +extern int hid_lgff_init(struct hid_device* hid);
7016 +extern int hid_pid_init(struct hid_device* hid);
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
7023 +static int (*inits[])(struct hid_device*) = {
7024 +#ifdef CONFIG_LOGITECH_FF
7027 +#ifdef CONFIG_HID_PID
7033 +int hid_ff_init(struct hid_device* hid)
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
7046 + dbg("hid_ff_init could not find initializer");
7049 diff -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
7057 * Copyright (c) 2000-2001 Vojtech Pavlik
7059 - * USB HID to Linux Input mapping module
7061 - * Sponsored by SuSE
7062 + * USB HID to Linux Input mapping
7067 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
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>
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}};
7089 static void hidinput_configure_usage(struct hid_device *device, struct hid_field *field, struct hid_usage *usage)
7091 struct input_dev *input = &device->input;
7096 switch (usage->hid & HID_USAGE_PAGE) {
7099 case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
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;
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;
7120 + case 0x0e0: is_abs = 1;
7121 + usage->code = ABS_VOLUME;
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;
7129 case 0x18a: usage->code = KEY_MAIL; break;
7130 case 0x192: usage->code = KEY_CALC; break;
7131 case 0x194: usage->code = KEY_FILE; break;
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;
7139 default: usage->code = KEY_UNKNOWN; break;
7143 + usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
7145 + usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
7149 + case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
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;
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;
7167 + default: usage->code = KEY_UNKNOWN; break;
7171 @@ -344,16 +377,28 @@
7172 static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
7174 struct hid_device *hid = dev->private;
7175 - struct hid_field *field = NULL;
7178 - if ((offset = hid_find_field(hid, type, code, &field)) == -1) {
7179 - warn("event field not found");
7181 + warn("hid input event");
7183 +#ifdef CONFIG_HID_FF
7184 + if (type == EV_FF) {
7185 + return hid_ff_event(hid, dev, type, code, value);
7191 + struct hid_field *field = NULL;
7194 + if ((offset = hid_find_field(hid, type, code, &field)) == -1) {
7195 + warn("event field not found");
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);
7207 @@ -361,12 +406,22 @@
7208 static int hidinput_open(struct input_dev *dev)
7210 struct hid_device *hid = dev->private;
7212 +#ifdef CONFIG_HID_FF
7216 return hid_open(hid);
7219 static void hidinput_close(struct input_dev *dev)
7221 struct hid_device *hid = dev->private;
7223 +#ifdef CONFIG_HID_FF
7224 + hid_ff_close(hid);
7231 hid->input.event = hidinput_input_event;
7232 hid->input.open = hidinput_open;
7233 hid->input.close = hidinput_close;
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;
7241 diff -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
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)
7256 + * Copyright (c) 2002 Johann Deneux
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.
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.
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
7274 + * Should you need to contact me, the author, you can do so by
7275 + * e-mail - mail your message to <deneux@ifrance.com>
7279 + Support periodic, custom and condition effects.
7280 + Support gain setting + default spring.
7283 +#include <linux/input.h>
7284 +#include <linux/sched.h>
7287 +#include <linux/usb.h>
7289 +#include <linux/circ_buf.h>
7292 +#include "fixp-arith.h"
7295 +/* Periodicity of the update */
7296 +#define PERIOD (HZ/10)
7298 +#define RUN_AT(t) (jiffies + (t))
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
7306 +// For lgff_device::flags
7307 +#define DEVICE_CLOSING 0 /* The driver is being unitialised */
7309 +#define LGFF_EFFECTS 8
7311 +struct device_type {
7317 +struct lgff_effect {
7320 + struct ff_effect effect;
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 */
7327 +struct lgff_device {
7328 + struct hid_device* hid;
7330 + struct hid_report* constant;
7331 + struct hid_report* rumble;
7332 + struct hid_report* condition;
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 */
7339 + unsigned long flags[1]; /* Contains various information about the
7340 + state of the driver for this device */
7342 + struct timer_list timer;
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);
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*);
7360 +static signed short ff_rumble[] = {
7365 +static signed short ff_joystick[] = {
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}
7379 +int hid_lgff_init(struct hid_device* hid)
7381 + struct lgff_device *private;
7382 + struct hid_report* report;
7383 + struct hid_field* field;
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
7393 + /* Unsupported or unknown devices */
7394 + default: return 1;
7398 + case 0x6a3: // Saitek
7399 + switch (hid->dev->descriptor.idProduct) {
7400 + case 0xff12: // Cyborg 3D Force
7402 + default: return 1;
7406 + default: return 1;
7409 + /* Find the report to use */
7410 + if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
7411 + err("No output report found");
7414 + /* Check that the report looks ok */
7415 + report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
7417 + err("NULL output report");
7420 + field = report->field[0];
7422 + err("NULL field");
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;
7432 + hid_lgff_input_init(hid);
7435 + private->constant = hid_lgff_duplicate_report(report);
7436 + if (!private->constant) {
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;
7445 + private->rumble = hid_lgff_duplicate_report(report);
7446 + if (!private->rumble) {
7447 + hid_lgff_delete_report(private->constant);
7451 + private->rumble->field[0]->value[0] = 0x03;
7452 + private->rumble->field[0]->value[1] = 0x42;
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);
7463 + private->hid = hid;
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;
7470 + /* Event and exit callbacks */
7471 + hid->ff_exit = hid_lgff_exit;
7472 + hid->ff_event = hid_lgff_event;
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 */
7479 + printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <deneux@ifrance.com>\n");
7484 +static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
7486 + struct hid_report* ret;
7488 + ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
7489 + if (!ret) return NULL;
7492 + ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
7493 + if (!ret->field[0]) {
7497 + *ret->field[0] = *report->field[0];
7499 + ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL);
7500 + if (!ret->field[0]->value) {
7501 + kfree(ret->field[0]);
7505 + memset(ret->field[0]->value, 0, sizeof(s32[8]));
7510 +static void hid_lgff_delete_report(struct hid_report* report)
7513 + kfree(report->field[0]->value);
7514 + kfree(report->field[0]);
7519 +static void hid_lgff_input_init(struct hid_device* hid)
7521 + struct device_type* dev = devices;
7523 + u16 idVendor = hid->dev->descriptor.idVendor;
7524 + u16 idProduct = hid->dev->descriptor.idProduct;
7526 + while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
7531 + while (*ff >= 0) {
7532 + set_bit(*ff, hid->input.ffbit);
7536 + hid->input.upload_effect = hid_lgff_upload_effect;
7537 + hid->input.flush = hid_lgff_flush;
7539 + set_bit(EV_FF, hid->input.evbit);
7540 + hid->input.ff_effects_max = LGFF_EFFECTS;
7543 +static void hid_lgff_exit(struct hid_device* hid)
7545 + struct lgff_device *lgff = hid->ff_private;
7547 + set_bit(DEVICE_CLOSING, lgff->flags);
7548 + del_timer_sync(&lgff->timer);
7550 + hid_lgff_delete_report(lgff->condition);
7551 + hid_lgff_delete_report(lgff->rumble);
7552 + hid_lgff_delete_report(lgff->constant);
7557 +static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
7558 + unsigned int type, unsigned int code, int value)
7560 + struct lgff_device *lgff = hid->ff_private;
7561 + struct lgff_effect *effect = lgff->effects + code;
7562 + unsigned long flags;
7564 + if (type != EV_FF) return -EINVAL;
7565 + if (value < 0) return -EINVAL;
7567 + spin_lock_irqsave(&lgff->lock, flags);
7570 + if (test_bit(EFFECT_STARTED, effect->flags)) {
7571 + spin_unlock_irqrestore(&lgff->lock, flags);
7574 + if (test_bit(EFFECT_PLAYING, effect->flags)) {
7575 + spin_unlock_irqrestore(&lgff->lock, flags);
7579 + effect->count = value;
7581 + if (effect->effect.replay.delay) {
7582 + set_bit(EFFECT_STARTED, effect->flags);
7584 + set_bit(EFFECT_PLAYING, effect->flags);
7586 + effect->started_at = jiffies;
7588 + else { /* value == 0 */
7589 + clear_bit(EFFECT_STARTED, effect->flags);
7590 + clear_bit(EFFECT_PLAYING, effect->flags);
7593 + spin_unlock_irqrestore(&lgff->lock, flags);
7599 +/* Erase all effects this process owns */
7600 +static int hid_lgff_flush(struct input_dev *dev, struct file *file)
7602 + struct hid_device *hid = dev->private;
7603 + struct lgff_device *lgff = hid->ff_private;
7606 + for (i=0; i<dev->ff_effects_max; ++i) {
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)) {
7615 + if (hid_lgff_erase(dev, i))
7616 + warn("erase effect %d failed", i);
7624 +static int hid_lgff_erase(struct input_dev *dev, int id)
7626 + struct hid_device *hid = dev->private;
7627 + struct lgff_device *lgff = hid->ff_private;
7628 + unsigned long flags;
7630 + spin_lock_irqsave(&lgff->lock, flags);
7631 + lgff->effects[id].flags[0] = 0;
7632 + spin_unlock_irqrestore(&lgff->lock, flags);
7637 +static int hid_lgff_upload_effect(struct input_dev* input,
7638 + struct ff_effect* effect)
7640 + struct hid_device *hid = input->private;
7641 + struct lgff_device *lgff = hid->ff_private;
7642 + struct lgff_effect new;
7644 + unsigned long flags;
7646 + dbg("ioctl rumble");
7648 + if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
7650 + spin_lock_irqsave(&lgff->lock, flags);
7652 + if (effect->id == -1) {
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);
7662 + lgff->effects[i].owner = current->pid;
7663 + lgff->effects[i].flags[0] = 0;
7664 + set_bit(EFFECT_USED, lgff->effects[i].flags);
7668 + new = lgff->effects[id];
7670 + new.effect = *effect;
7672 + if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
7673 + || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {
7675 + /* Changing replay parameters is not allowed (for the time
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);
7683 + lgff->effects[id] = new;
7686 + lgff->effects[id] = new;
7689 + spin_unlock_irqrestore(&lgff->lock, flags);
7693 +static void hid_lgff_compute_constant(struct lgff_effect *effect,
7697 + unsigned long now = jiffies;
7700 + // During attack ?
7701 + if (effect->effect.u.constant.envelope.attack_length &&
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");
7713 + else if (effect->effect.replay.length &&
7714 + effect->effect.u.constant.envelope.fade_length &&
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");
7726 + level = effect->effect.u.constant.level;
7727 +// dbg("During middle");
7729 +// dbg("level = %d", level);
7731 + degrees = effect->effect.direction * 360 >> 16;
7732 + *x += fixp_mult(fixp_sin(degrees),
7734 + *y += fixp_mult(-fixp_cos(degrees),
7738 +static void hid_lgff_timer(unsigned long timer_data)
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
7747 + spin_lock_irqsave(&lgff->lock, flags);
7749 + for (i=0; i<LGFF_EFFECTS; ++i) {
7750 + struct lgff_effect* effect = lgff->effects +i;
7752 + if (test_bit(EFFECT_PLAYING, effect->flags)) {
7754 + switch (effect->effect.type) {
7756 + hid_lgff_compute_constant(effect, &x, &y);
7759 + right += effect->effect.u.rumble.strong_magnitude;
7760 + left += effect->effect.u.rumble.weak_magnitude;
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);
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);
7781 + effect->started_at = jiffies;
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);
7800 +#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
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);
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);
7826 + if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
7827 + lgff->timer.expires = RUN_AT(PERIOD);
7828 + add_timer(&lgff->timer);
7831 + spin_unlock_irqrestore(&lgff->lock, flags);
7833 diff -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
7843 * Copyright (c) 1999 Andreas Gal
7844 * Copyright (c) 2000-2001 Vojtech Pavlik
7846 - * Sponsored by SuSE
7851 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
7860 #include <linux/types.h>
7862 #define USB_INTERFACE_CLASS_HID 3
7865 + * HID class requests
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
7876 + * HID class descriptor types
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)
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
7897 #define HID_USAGE 0x0000ffff
7900 __s32 logical_maximum;
7901 __s32 physical_minimum;
7902 __s32 physical_maximum;
7903 - unsigned unit_exponent;
7904 + __s32 unit_exponent;
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;
7915 struct hid_report *report; /* associated report */
7916 + unsigned index; /* index into report->field[] */
7919 #define HID_MAX_FIELDS 64
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 */
7929 @@ -284,16 +302,20 @@
7930 #define HID_REPORT_TYPES 3
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
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;
7944 #define HID_CLAIMED_INPUT 1
7945 #define HID_CLAIMED_HIDDEV 2
7947 +#define HID_CTRL_RUNNING 1
7948 +#define HID_OUT_RUNNING 2
7950 struct hid_device { /* device report descriptor */
7953 @@ -306,12 +328,23 @@
7954 struct usb_device *dev; /* USB device */
7955 int ifnum; /* USB interface number */
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) */
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 */
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 */
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 */
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 */
7986 + wait_queue_head_t wait; /* For sleeping */
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 #) */
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);
7999 #define HID_GLOBAL_STACK_SIZE 4
8000 @@ -352,32 +394,44 @@
8001 struct hid_class_descriptor desc[1];
8002 } __attribute__ ((packed));
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 *);
8009 #include "hid-debug.h"
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)
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 *);
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) { }
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))
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);
8043 +#ifdef CONFIG_HID_FF
8045 +int hid_ff_init(struct hid_device *hid);
8046 +static inline void hid_ff_exit(struct hid_device *hid)
8048 + if (hid->ff_exit) hid->ff_exit(hid);
8051 +static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input,
8052 + unsigned int type, unsigned int code, int value)
8054 + if (hid->ff_event) return hid->ff_event(hid, input, type, code, value);
8058 diff -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
8064 struct hiddev_list {
8065 - struct hiddev_event buffer[HIDDEV_BUFFER_SIZE];
8066 + struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
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
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)
8080 struct hiddev *hiddev = hid->hiddev;
8081 struct hiddev_list *list = hiddev->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);
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);
8100 struct hiddev_list *list = file->private_data;
8101 struct hiddev_list **listptr;
8104 listptr = &list->hiddev->list;
8105 hiddev_fasync(-1, file, 0);
8116 static int hiddev_open(struct inode * inode, struct file * file) {
8117 struct hiddev_list *list;
8119 - int i = MINOR(inode->i_rdev) - HIDDEV_MINOR_BASE;
8120 + int i = minor(inode->i_rdev) - HIDDEV_MINOR_BASE;
8122 if (i >= HIDDEV_MINORS || !hiddev_table[i])
8124 @@ -259,43 +260,67 @@
8126 DECLARE_WAITQUEUE(wait, current);
8127 struct hiddev_list *list = file->private_data;
8131 - if (list->head == list->tail) {
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);
8138 - while (list->head == list->tail) {
8139 + if (count < event_size) return 0;
8141 - if (file->f_flags & O_NONBLOCK) {
8145 - if (signal_pending(current)) {
8146 - retval = -ERESTARTSYS;
8149 - if (!list->hiddev->exist) {
8152 + while (retval == 0) {
8153 + if (list->head == list->tail) {
8154 + add_wait_queue(&list->hiddev->wait, &wait);
8155 + set_current_state(TASK_INTERRUPTIBLE);
8157 + while (list->head == list->tail) {
8158 + if (file->f_flags & O_NONBLOCK) {
8162 + if (signal_pending(current)) {
8163 + retval = -ERESTARTSYS;
8166 + if (!list->hiddev->exist) {
8175 + set_current_state(TASK_RUNNING);
8176 + remove_wait_queue(&list->hiddev->wait, &wait);
8179 - set_current_state(TASK_RUNNING);
8180 - remove_wait_queue(&list->hiddev->wait, &wait);
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)))
8203 + retval += sizeof(struct hiddev_event);
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)))
8210 + retval += sizeof(struct hiddev_usage_ref);
8213 + list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
8219 @@ -360,6 +385,25 @@
8220 return copy_to_user((void *) arg, &dinfo, sizeof(dinfo));
8224 + return put_user(list->flags, (int *) arg);
8229 + if (get_user(newflags, (int *) arg))
8232 + if ((newflags & ~HIDDEV_FLAGS) != 0 ||
8233 + ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
8234 + (newflags & HIDDEV_FLAG_UREF) == 0))
8237 + list->flags = newflags;
8246 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
8249 - hid_read_report(hid, report);
8250 + hid_submit_report(hid, report, USB_DIR_IN);
8255 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
8258 - hid_write_report(hid, report);
8259 + hid_submit_report(hid, report, USB_DIR_OUT);
8263 diff -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
8267 #include <asm/unaligned.h>
8269 #define OHCI_USE_NPS // force NoPowerSwitching mode
8270 -// #define OHCI_VERBOSE_DEBUG /* not always helpful */
8271 +#undef OHCI_VERBOSE_DEBUG /* not always helpful */
8273 #include "usb-ohci.h"
8275 diff -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
8280 input_register_device(&kbd->dev);
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);
8289 diff -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
8294 input_register_device(&mouse->dev);
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);
8303 diff -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
8307 usb_set_report(dev, ifnum, 3, 5, rep_data, 0);
8308 usb_set_report(dev, ifnum, 3, 6, rep_data, 0);
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);
8317 diff -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
8327 * Copyright (c) 1999-2000 Vojtech Pavlik
8330 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
8340 @@ -119,12 +119,17 @@
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
8348 +#define HID_FIELD_INDEX_NONE 0xffffffff
8354 -#define HID_VERSION 0x010002
8355 +#define HID_VERSION 0x010003
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)
8377 + * Flags to be used in HIDIOCSFLAG
8379 +#define HIDDEV_FLAG_UREF 0x1
8380 +#define HIDDEV_FLAG_REPORT 0x2
8381 +#define HIDDEV_FLAGS 0x3
8383 /* To traverse the input report descriptor info for a HID device, perform the
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);
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) { }
8401 diff -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
8411 - * Copyright (c) 1999-2000 Vojtech Pavlik
8413 - * Sponsored by SuSE
8414 + * Copyright (c) 1999-2001 Vojtech Pavlik
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.
8426 * You should have received a copy of the GNU General Public License
8428 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
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 */
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 */
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 */
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 */
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 */
8467 +#define EV_PWR 0x16
8468 +#define EV_FF_STATUS 0x17
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
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
8496 -#define KEY_UNKNOWN 220
8497 +#define KEY_UNKNOWN 240
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
8505 +#define BTN_WHEEL 0x150
8506 +#define BTN_GEAR_DOWN 0x150
8507 +#define BTN_GEAR_UP 0x151
8509 #define KEY_MAX 0x1ff
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
8522 @@ -485,67 +512,89 @@
8523 #define BUS_I2C 0x18
8526 + * Values describing the status of an effect
8528 +#define FF_STATUS_STOPPED 0x00
8529 +#define FF_STATUS_PLAYING 0x01
8530 +#define FF_STATUS_MAX 0x01
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)
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 */
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) */
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 */
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;
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
8577 - * It is a bit array (ie to enable axes X and Y, use BIT(ABS_X) | BIT(ABS_Y)
8582 +struct ff_ramp_effect {
8583 + __s16 start_level;
8585 + struct ff_envelope envelope;
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 */
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 */
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 */
8606 struct ff_periodic_effect {
8607 __u16 waveform; /* Kind of wave (sine, square...) */
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 */
8616 - struct ff_shape shape;
8617 + struct ff_envelope envelope;
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 */
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.
8631 +struct ff_rumble_effect {
8632 + __u16 strong_magnitude; /* Magnitude of the heavy motor */
8633 + __u16 weak_magnitude; /* Magnitude of the light one */
8637 @@ -554,36 +603,30 @@
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.
8647 + __u16 direction; /* Direction. 0 deg -> 0x0000 (down)
8648 + 90 deg -> 0x4000 (left)
8649 + 180 deg -> 0x8000 (up)
8650 + 270 deg -> 0xC000 (right)
8653 struct ff_trigger trigger;
8654 struct ff_replay replay;
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;
8667 - * Buttons that can trigger effects. Use for example FF_BTN(BTN_TRIGGER) to
8668 - * access the bitmap.
8671 -#define FF_BTN(x) ((x) - BTN_MISC + FF_BTN_OFFSET)
8672 -#define FF_BTN_OFFSET 0x00
8675 - * Force feedback axis mappings. Use FF_ABS() to access the bitmap.
8678 -#define FF_ABS(x) ((x) + FF_ABS_OFFSET)
8679 -#define FF_ABS_OFFSET 0x40
8682 * Force feedback effect types
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
8694 * Force feedback periodic effect types
8703 unsigned short idbus;
8704 unsigned short idvendor;
8705 unsigned short idproduct;
8707 unsigned int repeat_key;
8708 struct timer_list timer;
8710 + struct pm_dev *pm_dev;
8713 int abs[ABS_MAX + 1];
8714 int rep[REP_MAX + 1];
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;
8730 + * Structure for hotplug & device<->driver matching.
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
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
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)
8752 +struct input_device_id {
8754 + unsigned long flags;
8756 + unsigned short idbus;
8757 + unsigned short idvendor;
8758 + unsigned short idproduct;
8759 + unsigned short idversion;
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)];
8770 + unsigned long driver_info;
8773 struct input_handler {
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);
8782 struct file_operations *fops;
8786 + struct input_device_id *id_table;
8788 struct input_handle *handle;
8789 struct input_handler *next;
8796 struct input_dev *dev;
8797 struct input_handler *handler;
8799 int input_open_device(struct input_handle *);
8800 void input_close_device(struct input_handle *);
8802 +int input_accept_process(struct input_handle *handle, struct file *file);
8803 +int input_flush_device(struct input_handle* handle, struct file* file);
8805 devfs_handle_t input_register_minor(char *name, int minor, int minor_base);
8806 void input_unregister_minor(devfs_handle_t handle);
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)
8817 diff -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
8827 - * Copyright (C) 1999 Vojtech Pavlik
8829 - * Sponsored by SuSE
8830 + * Copyright (C) 1999-2001 Vojtech Pavlik
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.
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.
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
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
8859 * The serial port set type ioctl.
8862 +#include <asm/errno.h>
8863 #include <linux/ioctl.h>
8865 #define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
8875 + unsigned short idbus;
8876 + unsigned short idvendor;
8877 + unsigned short idproduct;
8878 + unsigned short idversion;
8883 int (*write)(struct serio *, unsigned char);
8884 int (*open)(struct serio *);
8885 void (*close)(struct serio *);
8887 struct serio_dev *dev;
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 *);
8903 static __inline__ int serio_write(struct serio *serio, unsigned char data)
8905 - return serio->write(serio, data);
8906 + return serio->write?serio->write(serio, data):-ENOSYS;
8909 +static __inline__ void serio_dev_write_wakeup(struct serio *serio)
8911 + if (serio->dev && serio->dev->write_wakeup) {
8912 + serio->dev->write_wakeup(serio);
8916 #define SERIO_TIMEOUT 1
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
8925 #define SERIO_ID 0xff00UL