bk://kernel.bkbits.net/vojtech/input
vojtech@suse.cz|ChangeSet|20040615082533|47491 vojtech

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/06/18 15:39:10-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/hiddev.c
#   2004/06/18 15:39:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/tsdev.c
#   2004/06/18 15:39:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/misc/uinput.c
#   2004/06/18 15:39:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/18 12:16:15-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# include/linux/serio.h
#   2004/06/18 12:16:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mouse/Kconfig
#   2004/06/18 12:16:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/keyboard/atkbd.c
#   2004/06/18 12:16:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/char/keyboard.c
#   2004/06/18 12:16:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/18 12:16:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/13 11:19:52-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/13 11:19:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/12 13:55:01+02:00 vojtech@suse.cz 
#   Input: rearrangements and cleanups in serio.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/serio/serio.c
#   2004/06/12 13:54:52+02:00 vojtech@suse.cz +102 -89
#   Input: rearrangements and cleanups in serio.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/11 23:04:12+02:00 vojtech@suse.cz 
#   Merge bkbits:input into suse.cz:/home/vojtech/bk/input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/11 23:04:03+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/11 23:04:02+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/11 23:04:02+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/11 23:04:02+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/11 23:04:02+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/11 23:04:02+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/11 12:10:29+02:00 vojtech@suse.cz 
#   Merge bkbits:input into suse.cz:/data/bk/input
# 
# drivers/input/serio/i8042.c
#   2004/06/11 12:10:25+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/09 12:00:59-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/09 12:00:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/09 07:33:13+02:00 vojtech@suse.cz 
#   Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/09 07:33:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/09 07:33:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/09 07:33:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/09 07:33:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/09 07:33:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/09 07:33:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/09 07:33:08+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/09 07:33:08+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/09 07:33:08+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/09 07:33:08+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/09 07:33:08+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/09 07:33:08+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/08 21:48:02-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/08 21:47:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/08 22:57:09+02:00 vojtech@suse.cz 
#   Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/08 22:57:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/07 14:09:01-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# drivers/input/serio/i8042.c
#   2004/06/07 14:08:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/07 14:08:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/07 14:08:12-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/mtouchusb.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/i8042.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/06/07 14:08:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/07 11:46:31+02:00 vojtech@suse.cz 
#   Merge bkbits:input into suse.cz:/home/vojtech/bk/input
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/07 11:46:27+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/07 11:41:45+02:00 vojtech@suse.cz 
#   Merge bkbits:input into suse.cz:/home/vojtech/bk/input
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/07 11:41:40+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/06 22:54:32-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# include/linux/compat_ioctl.h
#   2004/06/06 22:54:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/compat_ioctl.c
#   2004/06/06 22:54:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/06/06 22:54:28-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/06 22:54:28-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/06 22:53:42-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/06 22:53:39-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/06 20:13:56+02:00 vojtech@suse.cz 
#   input: Remove OSB4/Profusion hack in i8042, as it's handled by
#          DMI blacklist now.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/serio/i8042.c
#   2004/06/06 20:13:43+02:00 vojtech@suse.cz +1 -10
#   input: Remove OSB4/Profusion hack in i8042, as it's handled by
#          DMI blacklist now.
# 
# ChangeSet
#   2004/06/06 19:15:17+02:00 vojtech@suse.cz 
#   Merge bk://dtor.bkbits.net/input into suse.cz:/home/vojtech/bk/input
# 
# drivers/input/serio/i8042.c
#   2004/06/06 19:15:13+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/06/06 19:15:13+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# Documentation/kernel-parameters.txt
#   2004/06/06 19:15:13+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/06 11:37:05-05:00 dtor_core@ameritech.net 
#   Input: mousedev - implement tapping for touchpads working in absolute
#          mode, such as Synaptics
#   
#   Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
# 
# drivers/input/mousedev.c
#   2004/06/06 11:36:50-05:00 dtor_core@ameritech.net +31 -7
#   Implement tapping for touchpads working in absolute mode
# 
# drivers/input/mouse/Kconfig
#   2004/06/06 11:36:50-05:00 dtor_core@ameritech.net +0 -2
#   Do not recommend proto=imps option for Synaptics since mousedev
#   now supports tapping
# 
# Documentation/kernel-parameters.txt
#   2004/06/06 11:36:50-05:00 dtor_core@ameritech.net +6 -0
#   mousedev.tap_time option documented
# 
# ChangeSet
#   2004/06/06 11:34:24-05:00 dtor_core@ameritech.net 
#   Input: mousedev - better handle button presses when under load
#   
#   Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
# 
# drivers/input/mousedev.c
#   2004/06/06 11:33:44-05:00 dtor_core@ameritech.net +104 -48
#   Better handle button presses under load, cleanups
# 
# ChangeSet
#   2004/06/06 15:05:20+02:00 vojtech@suse.cz 
#   Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input
# 
# fs/compat_ioctl.c
#   2004/06/06 15:05:15+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/06 11:56:42+02:00 zap@homelink.ru 
#   input: 
#   
#   From: Andrew Zabolotny <zap@homelink.ru>
#   
#   - Implement the 'raw' touchscreen protocol for backward compatibility
#     (/dev/input/ts[0-7] now speaks the protocol of the old /dev/h3600_ts, and
#     the /dev/input/tsraw[0-7] speaks the protocol of the old /dev/h3600_tsraw
#     device).
#   
#   - Support the ioctls for setting the calibration parameters.  The default
#     calibration matrix is computed from the xres,yres parameters (duplicate the
#     old behaviour), however this is not enough for a good translation from
#     touchscreen space to screen space.
#   
#   - Fixed a old bug in tsdev: on a pen motion event X1,Y1 -> X2,Y2 the driver
#     would output three events with coordinates: X1,Y1, X2,Y1, X2,Y2.  This
#     happened not only with coordinates, but with pressure too.
#   
#   - Update James's email address
#   
#   - Remove mention of Transvirtual Technologies: they no longer exist.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/tsdev.c
#   2004/06/06 11:56:33+02:00 zap@homelink.ru +186 -105
#   input: 
#   
#   From: Andrew Zabolotny <zap@homelink.ru>
#   
#   - Implement the 'raw' touchscreen protocol for backward compatibility
#     (/dev/input/ts[0-7] now speaks the protocol of the old /dev/h3600_ts, and
#     the /dev/input/tsraw[0-7] speaks the protocol of the old /dev/h3600_tsraw
#     device).
#   
#   - Support the ioctls for setting the calibration parameters.  The default
#     calibration matrix is computed from the xres,yres parameters (duplicate the
#     old behaviour), however this is not enough for a good translation from
#     touchscreen space to screen space.
#   
#   - Fixed a old bug in tsdev: on a pen motion event X1,Y1 -> X2,Y2 the driver
#     would output three events with coordinates: X1,Y1, X2,Y1, X2,Y2.  This
#     happened not only with coordinates, but with pressure too.
#   
#   - Update James's email address
#   
#   - Remove mention of Transvirtual Technologies: they no longer exist.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/06 11:37:43+02:00 herbert@gondor.apana.org.au 
#   input: Fix boundary checks for GUSAGE/SUSAGE in hiddev.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/usb/input/hiddev.c
#   2004/06/06 11:37:34+02:00 herbert@gondor.apana.org.au +13 -7
#   input: Fix boundary checks for GUSAGE/SUSAGE in hiddev.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/06 11:09:31+02:00 vojtech@suse.cz 
#   input: Add a missing extern i8042_dmi_loop.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/serio/i8042.c
#   2004/06/06 11:09:20+02:00 vojtech@suse.cz +1 -0
#   input: Add a missing extern i8042_dmi_loop.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/06 11:08:20+02:00 vojtech@suse.cz 
#   input: Make hardware rawmode optional for AT-keyboards, and check
#          for rawmode bits in keyboard.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# include/linux/input.h
#   2004/06/06 11:08:11+02:00 vojtech@suse.cz +1 -0
#   input: Make hardware rawmode optional for AT-keyboards, and check
#          for rawmode bits in keyboard.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/keyboard/atkbd.c
#   2004/06/06 11:08:11+02:00 vojtech@suse.cz +14 -2
#   input: Make hardware rawmode optional for AT-keyboards, and check
#          for rawmode bits in keyboard.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/char/keyboard.c
#   2004/06/06 11:08:11+02:00 vojtech@suse.cz +2 -1
#   input: Make hardware rawmode optional for AT-keyboards, and check
#          for rawmode bits in keyboard.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/05 16:57:37-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# fs/compat_ioctl.c
#   2004/06/05 16:57:34-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/05 11:39:52+02:00 vojtech@suse.cz 
#   Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input
# 
# include/linux/compat_ioctl.h
#   2004/06/05 11:39:47+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/04 07:18:00+02:00 wli@holomorphy.com 
#   input: Move CONFIG_USB_HIDDEV a little lower in hiddev.h, to fix
#          compilation breakage when it is not defined.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# include/linux/hiddev.h
#   2004/06/04 07:17:48+02:00 wli@holomorphy.com +1 -1
#   input: Move CONFIG_USB_HIDDEV a little lower in hiddev.h, to fix
#          compilation breakage when it is not defined.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/03 10:30:55-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# include/linux/compat_ioctl.h
#   2004/06/03 10:30:51-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/02 13:00:58-05:00 dtor_core@ameritech.net 
#   Input: logips2pp - do not call get_model_info 2 times
#   
#   Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
# 
# drivers/input/mouse/logips2pp.c
#   2004/06/02 13:00:30-05:00 dtor_core@ameritech.net +1 -1
#   Do not call get_model_info 2 times
# 
# ChangeSet
#   2004/06/02 12:56:24-05:00 dtor_core@ameritech.net 
#   Cset exclude: dtor_core@ameritech.net|ChangeSet|20040510063935|25419
# 
# drivers/input/serio/i8042.c
#   2004/06/02 12:56:02-05:00 dtor_core@ameritech.net +0 -0
#   Exclude
# 
# ChangeSet
#   2004/06/02 16:30:53+02:00 vojtech@suse.cz 
#   input: Add a missong dmi_noloop declaration in i8042.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/serio/i8042.c
#   2004/06/02 16:30:48+02:00 vojtech@suse.cz +1 -0
#   input: Add a missong dmi_noloop declaration in i8042.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/02 16:09:25+02:00 vojtech@suse.cz 
#   input: More locking improvements (and a fix) for serio. This
#          merges both my and Dmitry's changes.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/serio/serio.c
#   2004/06/02 16:09:19+02:00 vojtech@suse.cz +14 -12
#   input: More locking improvements (and a fix) for serio. This
#          merges both my and Dmitry's changes.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/02 15:46:14+02:00 vojtech@suse.cz 
#   input: Make atkbd.c's atkbd_command() function immune to keys being pressed
#          and scancodes coming from the keyboard while it's executing.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/keyboard/atkbd.c
#   2004/06/02 15:46:08+02:00 vojtech@suse.cz +8 -12
#   input: Make atkbd.c's atkbd_command() function immune to keys being pressed
#          and scancodes coming from the keyboard while it's executing.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/06/02 13:48:07+02:00 vojtech@suse.cz 
#   Merge suse.cz:/data/bk/compaq into suse.cz:/data/bk/input
# 
# drivers/input/serio/i8042.c
#   2004/06/02 13:48:04+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/02 13:44:20+02:00 vojtech@suse.cz 
#   input: Disable the AUX LoopBack command in i8042.c on Compaq ProLiant
#          8-way Xeon ProFusion systems, as it causes crashes and reboots
#          on these machines. DMI data is used for determining if the
#          workaround should be enabled.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/serio/i8042.c
#   2004/06/02 13:44:15+02:00 vojtech@suse.cz +13 -1
#   input: Disable the AUX LoopBack command in i8042.c on Compaq ProLiant
#          8-way Xeon ProFusion systems, as it causes crashes and reboots
#          on these machines. DMI data is used for determining if the
#          workaround should be enabled.
# 
# arch/i386/kernel/dmi_scan.c
#   2004/06/02 13:44:15+02:00 vojtech@suse.cz +31 -0
#   input: Disable the AUX LoopBack command in i8042.c on Compaq ProLiant
#          8-way Xeon ProFusion systems, as it causes crashes and reboots
#          on these machines. DMI data is used for determining if the
#          workaround should be enabled.
# 
# ChangeSet
#   2004/06/02 09:37:24+02:00 vojtech@suse.cz 
#   input: Fixes in serio locking. We need per-serio lock for passthrough
#          ports, some locks were missing, and spin_lock_irq was wishful
#          thinking in serio_interrupt. There is no guarantee
#          that serio_interrupt won't be called twice at the same time.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# include/linux/serio.h
#   2004/06/02 09:37:13+02:00 vojtech@suse.cz +3 -0
#   input: Fixes in serio locking. We need per-serio lock for passthrough
#          ports, some locks were missing, and spin_lock_irq was wishful
#          thinking in serio_interrupt. There is no guarantee
#          that serio_interrupt won't be called twice at the same time.
# 
# drivers/input/serio/serio.c
#   2004/06/02 09:37:13+02:00 vojtech@suse.cz +29 -26
#   input: Fixes in serio locking. We need per-serio lock for passthrough
#          ports, some locks were missing, and spin_lock_irq was wishful
#          thinking in serio_interrupt. There is no guarantee
#          that serio_interrupt won't be called twice at the same time.
# 
# ChangeSet
#   2004/05/31 16:15:23-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# fs/compat_ioctl.c
#   2004/05/31 16:15:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/05/31 16:15:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/05/31 16:15:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/05/31 16:15:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/31 16:25:29+02:00 vojtech@suse.cz 
#   input: Use raw events generated by atkbd in keyboard.c to implement true
#          rawmode for PS/2 keyboards.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/char/keyboard.c
#   2004/05/31 16:25:23+02:00 vojtech@suse.cz +19 -6
#   input: Use raw events generated by atkbd in keyboard.c to implement true
#          rawmode for PS/2 keyboards.
# 
# ChangeSet
#   2004/05/31 15:49:05+02:00 vojtech@suse.cz 
#   input: Add reporting of raw scancodes to atkbd.c
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# include/linux/input.h
#   2004/05/31 15:49:00+02:00 vojtech@suse.cz +1 -0
#   input: Add reporting of raw scancodes to atkbd.c
# 
# drivers/input/keyboard/atkbd.c
#   2004/05/31 15:49:00+02:00 vojtech@suse.cz +5 -3
#   input: Add reporting of raw scancodes to atkbd.c
# 
# ChangeSet
#   2004/05/31 15:11:41+02:00 vojtech@suse.cz 
#   input: Explicit variable access rules for psmouse.c, using bitops.
# 
# drivers/input/mouse/psmouse.h
#   2004/05/31 15:11:35+02:00 vojtech@suse.cz +7 -2
#   input: Explicit variable access rules for psmouse.c, using bitops.
# 
# drivers/input/mouse/psmouse-base.c
#   2004/05/31 15:11:35+02:00 vojtech@suse.cz +79 -50
#   input: Explicit variable access rules for psmouse.c, using bitops.
# 
# drivers/input/keyboard/atkbd.c
#   2004/05/31 15:11:35+02:00 vojtech@suse.cz +1 -1
#   input: Explicit variable access rules for psmouse.c, using bitops.
# 
# ChangeSet
#   2004/05/31 12:27:40+02:00 vojtech@suse.cz 
#   input: Return 0 from uinput poll if device isn't yet created.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/misc/uinput.c
#   2004/05/31 12:27:29+02:00 vojtech@suse.cz +1 -1
#   input: Return 0 from uinput poll if device isn't yet created.
# 
# ChangeSet
#   2004/05/30 16:57:22+02:00 vojtech@suse.cz 
#   input: Make atomicity and exclusive access to variables explicit
#   in atkbd.c, using bitops.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# drivers/input/keyboard/atkbd.c
#   2004/05/30 16:54:58+02:00 vojtech@suse.cz +89 -44
#   input: Make atomicity and exclusive access to variables explicit
#   in atkbd.c, using bitops.
#   
#   Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
# 
# ChangeSet
#   2004/05/30 16:12:14+02:00 vojtech@suse.cz 
#   Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input
# 
# fs/compat_ioctl.c
#   2004/05/30 16:12:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/05/30 16:12:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/05/30 16:12:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/05/30 16:12:09+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/29 22:04:32-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# include/linux/compat_ioctl.h
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/compat_ioctl.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/mtouchusb.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/05/29 22:04:29-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/29 22:03:41-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# fs/compat_ioctl.c
#   2004/05/29 22:03:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/serio/serport.c
#   2004/05/29 22:03:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/mousedev.c
#   2004/05/29 22:03:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/evdev.c
#   2004/05/29 22:03:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/29 14:27:40+02:00 vojtech@suse.cz 
#   Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input
# 
# include/linux/compat_ioctl.h
#   2004/05/29 14:27:35+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# fs/compat_ioctl.c
#   2004/05/29 14:27:35+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/usb/input/mtouchusb.c
#   2004/05/29 14:27:35+02:00 vojtech@suse.cz +0 -35
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/05/29 14:27:35+02:00 vojtech@suse.cz +0 -1
#   Auto merged
# 
# drivers/input/joystick/gf2k.c
#   2004/05/29 14:27:35+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/05/29 14:27:34+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/05/29 14:27:34+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/05/29 14:27:34+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/05/29 14:27:34+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/05/29 14:27:34+02:00 vojtech@suse.cz +0 -42
#   Auto merged
# 
# ChangeSet
#   2004/05/28 17:08:02-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/hiddev.c
#   2004/05/28 17:07:59-07:00 akpm@bix.(none) +0 -1
#   Auto merged
# 
# ChangeSet
#   2004/05/28 15:31:37-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# include/linux/compat_ioctl.h
#   2004/05/28 15:31:34-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/compat_ioctl.c
#   2004/05/28 15:31:34-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/input/hiddev.c
#   2004/05/28 15:31:34-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/28 22:57:43+02:00 vojtech@suse.cz 
#   input: Fix an oops in poll() on uinput.  Thanks to Dmitry Torokhov
#          for suggesting the fix.
# 
# drivers/input/misc/uinput.c
#   2004/05/28 22:57:31+02:00 vojtech@suse.cz +3 -0
#   input: Fix an oops in poll() on uinput. 
# 
# ChangeSet
#   2004/05/28 18:24:08+02:00 vojtech@suse.cz 
#   input: An attempt at fixing locking in i8042.c and serio.c
# 
# include/linux/serio.h
#   2004/05/28 18:24:02+02:00 vojtech@suse.cz +1 -1
#   input: An attempt at fixing locking in i8042.c and serio.c
# 
# drivers/input/serio/serio.c
#   2004/05/28 18:24:02+02:00 vojtech@suse.cz +54 -10
#   input: An attempt at fixing locking in i8042.c and serio.c
# 
# drivers/input/serio/i8042.c
#   2004/05/28 18:24:02+02:00 vojtech@suse.cz +4 -0
#   input: An attempt at fixing locking in i8042.c and serio.c
# 
# ChangeSet
#   2004/05/28 16:19:29+02:00 vojtech@suse.cz 
#   Cset exclude: dtor_core@ameritech.net|ChangeSet|20040510063935|25419
# 
# drivers/input/serio/i8042.c
#   2004/05/28 16:19:20+02:00 vojtech@suse.cz +0 -0
#   Exclude
# 
# ChangeSet
#   2004/05/18 23:51:28-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/input/joystick/gf2k.c
#   2004/05/18 23:51:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/analog.c
#   2004/05/18 23:51:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/joystick/adi.c
#   2004/05/18 23:51:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/vortex.c
#   2004/05/18 23:51:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/input/gameport/ns558.c
#   2004/05/18 23:51:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/19 00:13:58+02:00 akropel1@rochester.rr.com 
#   input: Add 64-bit compatible ioctls for hiddev.
# 
# include/linux/hiddev.h
#   2004/05/19 00:13:45+02:00 akropel1@rochester.rr.com +7 -1
#   input: Add 64-bit compatible ioctls for hiddev.
# 
# include/linux/compat_ioctl.h
#   2004/05/19 00:13:45+02:00 akropel1@rochester.rr.com +17 -0
#   input: Add 64-bit compatible ioctls for hiddev.
# 
# fs/compat_ioctl.c
#   2004/05/19 00:13:45+02:00 akropel1@rochester.rr.com +2 -0
#   input: Add 64-bit compatible ioctls for hiddev.
# 
# drivers/usb/input/hiddev.c
#   2004/05/19 00:13:45+02:00 akropel1@rochester.rr.com +1 -1
#   input: Add 64-bit compatible ioctls for hiddev.
# 
# ChangeSet
#   2004/05/14 21:33:47-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/usb/input/mtouchusb.c
#   2004/05/14 21:33:44-07:00 akpm@bix.(none) +0 -35
#   Auto merged
# 
# Documentation/usb/mtouchusb.txt
#   2004/05/14 21:33:44-07:00 akpm@bix.(none) +0 -42
#   Auto merged
# 
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	2004-06-20 13:12:54 -07:00
+++ b/Documentation/kernel-parameters.txt	2004-06-20 13:12:54 -07:00
@@ -652,6 +652,12 @@
 
 	mga=		[HW,DRM]
 
+	mousedev.tap_time=
+			[MOUSE] Maximum time between finger touching and
+			leaving touchpad surface for touch to be considered
+			a tap and be reported as a left button click (for
+			touchpads working in absolute mode only).
+			Format: <msecs>
 	mousedev.xres=	[MOUSE] Horizontal screen resolution, used for devices
 			reporting absolute coordinates, such as tablets
 	mousedev.yres=	[MOUSE] Vertical screen resolution, used for devices
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	2004-06-20 13:12:54 -07:00
+++ b/arch/i386/kernel/dmi_scan.c	2004-06-20 13:12:54 -07:00
@@ -15,6 +15,9 @@
 unsigned long dmi_broken;
 EXPORT_SYMBOL(dmi_broken);
 
+unsigned int i8042_dmi_noloop = 0;
+EXPORT_SYMBOL(i8042_dmi_noloop);
+
 int is_sony_vaio_laptop;
 int is_unsafe_smbus;
 int es7000_plat = 0;
@@ -401,6 +404,17 @@
 }
 
 /*
+ * Several HP Proliant (and maybe other OSB4/ProFusion) systems
+ * shouldn't use the AUX LoopBack command, or they crash or reboot.
+ */
+
+static __init int set_8042_noloop(struct dmi_blacklist *d)
+{
+	i8042_dmi_noloop = 1;
+	return 0;
+}
+
+/*
  * This bios swaps the APM minute reporting bytes over (Many sony laptops
  * have this problem).
  */
@@ -881,6 +895,23 @@
 			MATCH(DMI_BIOS_VERSION, "3A71"),
 			NO_MATCH, NO_MATCH,
 			} },
+
+	/*      
+	 * Several HP Proliant (and maybe other OSB4/ProFusion) systems
+	 * can't use i8042 in mux mode, or they crash or reboot.
+	 */                     
+
+	{ set_8042_noloop, "Compaq Proliant 8500", {
+			MATCH(DMI_SYS_VENDOR, "Compaq"),
+			MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			MATCH(DMI_PRODUCT_VERSION, "8500"),
+			NO_MATCH }},
+
+	{ set_8042_noloop, "Compaq Proliant DL760", {
+			MATCH(DMI_SYS_VENDOR, "Compaq"),
+			MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			MATCH(DMI_PRODUCT_VERSION, "DL760"),
+			NO_MATCH }},
 
 #ifdef	CONFIG_ACPI_BOOT
 	/*
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/char/keyboard.c	2004-06-20 13:12:54 -07:00
@@ -941,6 +941,9 @@
 
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SH_MPC1211)
 
+#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
+			((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
+
 static unsigned short x86_keycodes[256] =
 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
 	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
@@ -1007,6 +1010,8 @@
 
 #else
 
+#define HW_RAW(dev)	0
+
 #warning "Cannot generate rawmode keyboard for your architecture yet."
 
 static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
@@ -1019,7 +1024,15 @@
 }
 #endif
 
-void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
+void kbd_rawcode(unsigned char data)
+{
+	struct vc_data *vc = vc_cons[fg_console].d;
+	kbd = kbd_table + fg_console;
+	if (kbd->kbdmode == VC_RAW)
+		put_queue(vc, data);
+}
+
+void kbd_keycode(unsigned int keycode, int down, int hw_raw, struct pt_regs *regs)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
 	unsigned short keysym, *key_map;
@@ -1053,7 +1066,7 @@
 		return;
 #endif /* CONFIG_MAC_EMUMOUSEBTN */
 
-	if ((raw_mode = (kbd->kbdmode == VC_RAW)))
+	if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
 		if (emulate_raw(vc, keycode, !down << 7))
 			if (keycode < BTN_MISC)
 				printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
@@ -1148,11 +1161,12 @@
 }
 
 static void kbd_event(struct input_handle *handle, unsigned int event_type, 
-		      unsigned int keycode, int down)
+		      unsigned int event_code, int value)
 {
-	if (event_type != EV_KEY)
-		return;
-	kbd_keycode(keycode, down, handle->dev->regs);
+	if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
+		kbd_rawcode(value);
+	if (event_type == EV_KEY)
+		kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs);
 	tasklet_schedule(&keyboard_tasklet);
 	do_poke_blanked_console = 1;
 	schedule_console_callback();
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/keyboard/atkbd.c	2004-06-20 13:12:54 -07:00
@@ -47,6 +47,10 @@
 module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
 MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");
 
+static int atkbd_softraw = 1;
+module_param_named(softraw, atkbd_softraw, bool, 0);
+MODULE_PARM_DESC(softraw, "Use software generated rawmode");
+
 static int atkbd_scroll;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
@@ -164,34 +168,48 @@
 	{ ATKBD_SCR_CLICK, 0x60 },
 };
 
+#define ATKBD_FLAG_ACK		0	/* Waiting for ACK/NAK */
+#define ATKBD_FLAG_CMD		1	/* Waiting for command to finish */
+#define ATKBD_FLAG_CMD1		2	/* First byte of command response */
+#define ATKBD_FLAG_ID		3	/* First byte is not keyboard ID */
+#define ATKBD_FLAG_ENABLED	4	/* Waining for init to finish */
+
 /*
  * The atkbd control structure
  */
 
 struct atkbd {
-	unsigned char keycode[512];
-	struct input_dev dev;
-	struct serio *serio;
 
+	/* Written only during init */
 	char name[64];
 	char phys[32];
-	unsigned short id;
+	struct serio *serio;
+	struct input_dev dev;
+
 	unsigned char set;
-	unsigned int translated:1;
-	unsigned int extra:1;
-	unsigned int write:1;
+	unsigned short id;
+	unsigned char keycode[512];
+	unsigned char translated;
+	unsigned char extra;
+	unsigned char write;
+
+	/* Protected by FLAG_ACK */
+	unsigned char nak;
 
+	/* Protected by FLAG_CMD */
 	unsigned char cmdbuf[4];
 	unsigned char cmdcnt;
-	volatile signed char ack;
-	unsigned char emul;
-	unsigned int resend:1;
-	unsigned int release:1;
-	unsigned int bat_xl:1;
-	unsigned int enabled:1;
 
+	/* Accessed only from interrupt */
+	unsigned char emul;
+	unsigned char resend;
+	unsigned char release;
+	unsigned char bat_xl;
 	unsigned int last;
 	unsigned long time;
+
+	/* Flags */
+	unsigned long flags;
 };
 
 static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value)
@@ -224,7 +242,7 @@
 
 #if !defined(__i386__) && !defined (__x86_64__)
 	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
-		printk("atkbd.c: frame/parity error: %02x\n", flags);
+		printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags);
 		serio_write(serio, ATKBD_CMD_RESEND);
 		atkbd->resend = 1;
 		goto out;
@@ -234,24 +252,45 @@
 		atkbd->resend = 0;
 #endif
 
-	if (!atkbd->ack)
+	if (test_bit(ATKBD_FLAG_ACK, &atkbd->flags))
 		switch (code) {
 			case ATKBD_RET_ACK:
-				atkbd->ack = 1;
+				atkbd->nak = 0;
+				if (atkbd->cmdcnt) {
+					set_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+					set_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
+					set_bit(ATKBD_FLAG_ID, &atkbd->flags);
+				}
+				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 				goto out;
 			case ATKBD_RET_NAK:
-				atkbd->ack = -1;
+				atkbd->nak = 1;
+				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 				goto out;
 		}
 
-	if (atkbd->cmdcnt) {
-		atkbd->cmdbuf[--atkbd->cmdcnt] = code;
+	if (test_bit(ATKBD_FLAG_CMD, &atkbd->flags)) {
+
+		atkbd->cmdcnt--;
+		atkbd->cmdbuf[atkbd->cmdcnt] = code;
+
+		if (atkbd->cmdcnt == 1) {
+		    	if (code != 0xab && code != 0xac)
+				clear_bit(ATKBD_FLAG_ID, &atkbd->flags);
+			clear_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
+		}
+
+		if (!atkbd->cmdcnt)
+			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+
 		goto out;
 	}
 
-	if (!atkbd->enabled)
+	if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags))
 		goto out;
 
+	input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
+
 	if (atkbd->translated) {
 
 		if (atkbd->emul ||
@@ -270,6 +309,7 @@
 
 	switch (code) {
 		case ATKBD_RET_BAT:
+			clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
 			serio_rescan(atkbd->serio);
 			goto out;
 		case ATKBD_RET_EMUL0:
@@ -300,6 +340,9 @@
 		code |= (atkbd->set != 3) ? 0x80 : 0x100;
 	}
 
+	if (atkbd->keycode[code] != ATKBD_KEY_NULL)
+		input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code);
+
 	switch (atkbd->keycode[code]) {
 		case ATKBD_KEY_NULL:
 			break;
@@ -376,18 +419,20 @@
 
 static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
 {
-	int timeout = 20000; /* 200 msec */
-	atkbd->ack = 0;
+	int timeout = 200000; /* 200 msec */
 
 #ifdef ATKBD_DEBUG
 	printk(KERN_DEBUG "atkbd.c: Sent: %02x\n", byte);
 #endif
+
+	set_bit(ATKBD_FLAG_ACK, &atkbd->flags);
+	clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
 	if (serio_write(atkbd->serio, byte))
 		return -1;
+	while (test_bit(ATKBD_FLAG_ACK, &atkbd->flags) && timeout--) udelay(1);
+	clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 
-	while (!atkbd->ack && timeout--) udelay(10);
-
-	return -(atkbd->ack <= 0);
+	return -atkbd->nak;
 }
 
 /*
@@ -405,7 +450,7 @@
 	atkbd->cmdcnt = receive;
 
 	if (command == ATKBD_CMD_RESET_BAT)
-		timeout = 2000000; /* 2 sec */
+		timeout = 4000000; /* 4 sec */
 
 	if (receive && param)
 		for (i = 0; i < receive; i++)
@@ -413,38 +458,40 @@
 
 	if (command & 0xff)
 		if (atkbd_sendbyte(atkbd, command & 0xff))
-			return (atkbd->cmdcnt = 0) - 1;
+			return -1;
 
 	for (i = 0; i < send; i++)
 		if (atkbd_sendbyte(atkbd, param[i]))
-			return (atkbd->cmdcnt = 0) - 1;
-
-	while (atkbd->cmdcnt && timeout--) {
+			return -1;
 
-		if (atkbd->cmdcnt == 1 &&
-		    command == ATKBD_CMD_RESET_BAT && timeout > 100000)
-			timeout = 100000;
+	while (test_bit(ATKBD_FLAG_CMD, &atkbd->flags) && timeout--) {
 
-		if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID &&
-		    atkbd->cmdbuf[1] != 0xab && atkbd->cmdbuf[1] != 0xac) {
-			atkbd->cmdcnt = 0;
-			break;
+		if (!test_bit(ATKBD_FLAG_CMD1, &atkbd->flags)) {
+		    
+			if (command == ATKBD_CMD_RESET_BAT && timeout > 100000)
+				timeout = 100000;
+
+			if (command == ATKBD_CMD_GETID && !test_bit(ATKBD_FLAG_ID, &atkbd->flags)) {
+				clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+				atkbd->cmdcnt = 0;
+				break;
+			}
 		}
 
 		udelay(1);
 	}
 
+	clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+
 	if (param)
 		for (i = 0; i < receive; i++)
 			param[i] = atkbd->cmdbuf[(receive - 1) - i];
 
 	if (command == ATKBD_CMD_RESET_BAT && atkbd->cmdcnt == 1)
-		atkbd->cmdcnt = 0;
+		return 0;
 
-	if (atkbd->cmdcnt) {
-		atkbd->cmdcnt = 0;
+	if (atkbd->cmdcnt)
 		return -1;
-	}
 
 	return 0;
 }
@@ -672,6 +719,7 @@
 static void atkbd_disconnect(struct serio *serio)
 {
 	struct atkbd *atkbd = serio->private;
+	clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
 	input_unregister_device(&atkbd->dev);
 	serio_close(serio);
 	kfree(atkbd);
@@ -709,17 +757,22 @@
 			return;
 	}
 
+	if (!atkbd->write)
+		atkbd_softrepeat = 1;
+	if (atkbd_softrepeat)
+		atkbd_softraw = 1;
+
 	if (atkbd->write) {
-		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP) | BIT(EV_MSC);
 		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+	atkbd->dev.mscbit[0] = atkbd_softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
 
 	if (!atkbd_softrepeat) {
 		atkbd->dev.rep[REP_DELAY] = 250;
 		atkbd->dev.rep[REP_PERIOD] = 33;
-	}
+	} else atkbd_softraw = 1;
 
-	atkbd->ack = 1;
 	atkbd->serio = serio;
 
 	init_input_dev(&atkbd->dev);
@@ -754,8 +807,6 @@
 		atkbd->id = 0xab00;
 	}
 
-	atkbd->enabled = 1;
-
 	if (atkbd->extra) {
 		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
 		sprintf(atkbd->name, "AT Set 2 Extra keyboard");
@@ -797,6 +848,8 @@
 
 	input_register_device(&atkbd->dev);
 
+	set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
+
 	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
 }
 
@@ -831,6 +884,8 @@
 		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
 			return -1;
 	}
+
+	set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
 
 	return 0;
 }
diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- a/drivers/input/misc/uinput.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/misc/uinput.c	2004-06-20 13:12:54 -07:00
@@ -279,6 +279,9 @@
 {
 	struct uinput_device *udev = file->private_data;
 
+	if (!test_bit(UIST_CREATED, &(udev->state)))
+		return 0;
+
 	poll_wait(file, &udev->waitq, wait);
 
 	if (udev->head != udev->tail)
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/mouse/Kconfig	2004-06-20 13:12:54 -07:00
@@ -30,8 +30,6 @@
 	  and a new verion of GPM at:
 		http://www.geocities.com/dt_or/gpm/gpm.html
 	  to take advantage of the advanced features of the touchpad.
-	  If you do not want install specialized drivers but want tapping
-	  working please use option psmouse.proto=imps.
 
 	  If unsure, say Y.
 
diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- a/drivers/input/mouse/logips2pp.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/mouse/logips2pp.c	2004-06-20 13:12:54 -07:00
@@ -277,7 +277,7 @@
 				protocol = PSMOUSE_PS2TPP;
 			}
 
-		} else if (get_model_info(model) != NULL) {
+		} else if (model_info != NULL) {
 
 			param[0] = param[1] = param[2] = 0;
 			ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/mouse/psmouse-base.c	2004-06-20 13:12:54 -07:00
@@ -142,34 +142,45 @@
 			printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
 				flags & SERIO_TIMEOUT ? " timeout" : "",
 				flags & SERIO_PARITY ? " bad parity" : "");
-		if (psmouse->acking) {
-			psmouse->ack = -1;
-			psmouse->acking = 0;
-		}
-		psmouse->pktcnt = 0;
+		psmouse->nak = 1;
+		clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+		clear_bit(PSMOUSE_FLAG_CMD,  &psmouse->flags);
 		goto out;
 	}
 
-	if (psmouse->acking) {
+	if (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags))
 		switch (data) {
 			case PSMOUSE_RET_ACK:
-				psmouse->ack = 1;
+				psmouse->nak = 0;
+				clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+				goto out;
 				break;
 			case PSMOUSE_RET_NAK:
-				psmouse->ack = -1;
-				break;
+				psmouse->nak = 1;
+				clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+				goto out;
 			default:
-				psmouse->ack = 1;	/* Workaround for mice which don't ACK the Get ID command */
-				if (psmouse->cmdcnt)
-					psmouse->cmdbuf[--psmouse->cmdcnt] = data;
-				break;
+				psmouse->nak = 0;	/* Workaround for mice which don't ACK the Get ID command */
+				clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+				if (!test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags))
+					goto out;
+
 		}
-		psmouse->acking = 0;
-		goto out;
-	}
 
-	if (psmouse->cmdcnt) {
-		psmouse->cmdbuf[--psmouse->cmdcnt] = data;
+	if (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags)) {
+
+		psmouse->cmdcnt--;
+		psmouse->cmdbuf[psmouse->cmdcnt] = data;
+
+		if (psmouse->cmdcnt == 1) {
+			if (data != 0xab && data != 0xac)
+				clear_bit(PSMOUSE_FLAG_ID, &psmouse->flags);
+			clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
+		}
+
+		if (!psmouse->cmdcnt)
+			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+
 		goto out;
 	}
 
@@ -242,18 +253,15 @@
 
 static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte)
 {
-	int timeout = 10000; /* 100 msec */
-	psmouse->ack = 0;
-	psmouse->acking = 1;
+	int timeout = 200000; /* 200 msec */
 
-	if (serio_write(psmouse->serio, byte)) {
-		psmouse->acking = 0;
+	set_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+	if (serio_write(psmouse->serio, byte))
 		return -1;
-	}
-
-	while (!psmouse->ack && timeout--) udelay(10);
+	while (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags) && timeout--) udelay(1);
+	clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
 
-	return -(psmouse->ack <= 0);
+	return -psmouse->nak;
 }
 
 /*
@@ -271,46 +279,62 @@
 	psmouse->cmdcnt = receive;
 
 	if (command == PSMOUSE_CMD_RESET_BAT)
-                timeout = 4000000; /* 4 sec */
+		timeout = 4000000; /* 4 sec */
 
-	/* initialize cmdbuf with preset values from param */
-	if (receive)
-	   for (i = 0; i < receive; i++)
-		psmouse->cmdbuf[(receive - 1) - i] = param[i];
+	if (receive && param)
+		for (i = 0; i < receive; i++)
+			psmouse->cmdbuf[(receive - 1) - i] = param[i];
+
+	if (receive) {
+		set_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+		set_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
+		set_bit(PSMOUSE_FLAG_ID, &psmouse->flags);
+	}
 
 	if (command & 0xff)
-		if (psmouse_sendbyte(psmouse, command & 0xff))
-			return (psmouse->cmdcnt = 0) - 1;
+		if (psmouse_sendbyte(psmouse, command & 0xff)) {
+			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+			return -1;
+		}
 
 	for (i = 0; i < send; i++)
-		if (psmouse_sendbyte(psmouse, param[i]))
-			return (psmouse->cmdcnt = 0) - 1;
+		if (psmouse_sendbyte(psmouse, param[i])) {
+			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+			return -1;
+		}
 
-	while (psmouse->cmdcnt && timeout--) {
+	while (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags) && timeout--) {
 
-		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT &&
-				timeout > 100000) /* do not run in a endless loop */
-			timeout = 100000; /* 1 sec */
-
-		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_GETID &&
-		    psmouse->cmdbuf[1] != 0xab && psmouse->cmdbuf[1] != 0xac) {
-			psmouse->cmdcnt = 0;
-			break;
+		if (!test_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags)) {
+		    
+			if (command == PSMOUSE_CMD_RESET_BAT && timeout > 100000)
+				timeout = 100000;
+
+			if (command == PSMOUSE_CMD_GETID && !test_bit(PSMOUSE_FLAG_ID, &psmouse->flags)) {
+				clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+				psmouse->cmdcnt = 0;
+				break;
+			}
 		}
 
 		udelay(1);
 	}
 
-	for (i = 0; i < receive; i++)
-		param[i] = psmouse->cmdbuf[(receive - 1) - i];
+	clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+
+	if (param)
+		for (i = 0; i < receive; i++)
+			param[i] = psmouse->cmdbuf[(receive - 1) - i];
+
+	if (command == PSMOUSE_CMD_RESET_BAT && psmouse->cmdcnt == 1)
+		return 0;
 
 	if (psmouse->cmdcnt)
-		return (psmouse->cmdcnt = 0) - 1;
+		return -1;
 
 	return 0;
 }
 
-
 /*
  * psmouse_sliced_command() sends an extended PS/2 command to the mouse
  * using sliced syntax, understood by advanced devices, such as Logitech
@@ -735,7 +759,12 @@
 	}
 
 	psmouse->state = PSMOUSE_CMD_MODE;
-	psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
+
+	clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+	clear_bit(PSMOUSE_FLAG_CMD,  &psmouse->flags);
+
+	psmouse->pktcnt = psmouse->out_of_sync = 0;
+
 	if (psmouse->reconnect) {
 	       if (psmouse->reconnect(psmouse))
 			return -1;
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/mouse/psmouse.h	2004-06-20 13:12:54 -07:00
@@ -22,6 +22,11 @@
 #define PSMOUSE_ACTIVATED	1
 #define PSMOUSE_IGNORE		2
 
+#define PSMOUSE_FLAG_ACK	0	/* Waiting for ACK/NAK */
+#define PSMOUSE_FLAG_CMD	1	/* Waiting for command to finish */
+#define PSMOUSE_FLAG_CMD1	2	/* First byte of command response */
+#define PSMOUSE_FLAG_ID		3	/* First byte is not keyboard ID */
+
 /* psmouse protocol handler return codes */
 typedef enum {
 	PSMOUSE_BAD_DATA,
@@ -54,11 +59,11 @@
 	unsigned long last;
 	unsigned long out_of_sync;
 	unsigned char state;
-	char acking;
-	volatile char ack;
+	unsigned char nak;
 	char error;
 	char devname[64];
 	char phys[32];
+	unsigned long flags;
 
 	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); 
 	int (*reconnect)(struct psmouse *psmouse);
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/mousedev.c	2004-06-20 13:12:54 -07:00
@@ -48,8 +48,13 @@
 module_param(yres, uint, 0);
 MODULE_PARM_DESC(yres, "Vertical screen resolution");
 
+static unsigned tap_time = 200;
+module_param(tap_time, uint, 0);
+MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
+
 struct mousedev_motion {
 	int dx, dy, dz;
+	unsigned long buttons;
 };
 
 struct mousedev {
@@ -62,21 +67,31 @@
 	struct input_handle handle;
 
 	struct mousedev_motion packet;
-	unsigned long buttons;
 	unsigned int pkt_count;
 	int old_x[4], old_y[4];
-	unsigned int touch;
+	unsigned long touch;
 };
 
+enum mousedev_emul {
+	MOUSEDEV_EMUL_PS2,
+	MOUSEDEV_EMUL_IMPS,
+	MOUSEDEV_EMUL_EXPS
+} __attribute__ ((packed));
+
+#define PACKET_QUEUE_LEN	16
 struct mousedev_list {
 	struct fasync_struct *fasync;
 	struct mousedev *mousedev;
 	struct list_head node;
-	int dx, dy, dz;
-	unsigned long buttons;
+
+	struct mousedev_motion packets[PACKET_QUEUE_LEN];
+	unsigned int head, tail;
+	spinlock_t packet_lock;
+
 	signed char ps2[6];
 	unsigned char ready, buffer, bufsiz;
-	unsigned char mode, imexseq, impsseq;
+	unsigned char imexseq, impsseq;
+	enum mousedev_emul mode;
 };
 
 #define MOUSEDEV_SEQ_LEN	6
@@ -165,30 +180,70 @@
 	}
 
 	if (value) {
-		set_bit(index, &mousedev->buttons);
-		set_bit(index, &mousedev_mix.buttons);
+		set_bit(index, &mousedev->packet.buttons);
+		set_bit(index, &mousedev_mix.packet.buttons);
 	} else {
-		clear_bit(index, &mousedev->buttons);
-		clear_bit(index, &mousedev_mix.buttons);
+		clear_bit(index, &mousedev->packet.buttons);
+		clear_bit(index, &mousedev_mix.packet.buttons);
 	}
 }
 
 static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
 {
 	struct mousedev_list *list;
+	struct mousedev_motion *p;
+	unsigned long flags;
 
 	list_for_each_entry(list, &mousedev->list, node) {
-		list->dx += packet->dx;
-		list->dy += packet->dy;
-		list->dz += packet->dz;
-		list->buttons = mousedev->buttons;
+		spin_lock_irqsave(&list->packet_lock, flags);
+
+		p = &list->packets[list->head];
+		if (list->ready && p->buttons != packet->buttons) {
+			unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN;
+			if (new_head != list->tail) {
+				p = &list->packets[list->head = new_head];
+				memset(p, 0, sizeof(struct mousedev_motion));
+			}
+		}
+
+		p->dx += packet->dx;
+		p->dy += packet->dy;
+		p->dz += packet->dz;
+		p->buttons = mousedev->packet.buttons;
+
 		list->ready = 1;
+
+		spin_unlock_irqrestore(&list->packet_lock, flags);
 		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 	}
 
 	wake_up_interruptible(&mousedev->wait);
 }
 
+static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
+{
+	if (!value) {
+		if (mousedev->touch &&
+		    !time_after(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) {
+			/*
+			 * Toggle left button to emulate tap.
+			 * We rely on the fact that mousedev_mix always has 0
+			 * motion packet so we won't mess current position.
+			 */
+			set_bit(0, &mousedev->packet.buttons);
+			set_bit(0, &mousedev_mix.packet.buttons);
+			mousedev_notify_readers(mousedev, &mousedev_mix.packet);
+			mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
+			clear_bit(0, &mousedev->packet.buttons);
+			clear_bit(0, &mousedev_mix.packet.buttons);
+		}
+		mousedev->touch = mousedev->pkt_count = 0;
+	}
+	else
+		if (!mousedev->touch)
+			mousedev->touch = jiffies;
+}
+
 static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
 	struct mousedev *mousedev = handle->private;
@@ -212,12 +267,8 @@
 
 		case EV_KEY:
 			if (value != 2) {
-				if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
-					/* Handle touchpad data */
-					mousedev->touch = value;
-					if (!mousedev->touch)
-						mousedev->pkt_count = 0;
-				}
+				if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+					mousedev_touchpad_touch(mousedev, value);
 				else
 					mousedev_key_event(mousedev, code, value);
 			}
@@ -237,7 +288,7 @@
 				mousedev_notify_readers(mousedev, &mousedev->packet);
 				mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
 
-				memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
+				mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
 			}
 			break;
 	}
@@ -322,6 +373,7 @@
 		return -ENOMEM;
 	memset(list, 0, sizeof(struct mousedev_list));
 
+	spin_lock_init(&list->packet_lock);
 	list->mousedev = mousedev_table[i];
 	list_add_tail(&list->node, &mousedev_table[i]->list);
 	file->private_data = list;
@@ -341,32 +393,56 @@
 	return 0;
 }
 
-static void mousedev_packet(struct mousedev_list *list, unsigned char off)
+static inline int mousedev_limit_delta(int delta, int limit)
 {
-	list->ps2[off] = 0x08 | ((list->dx < 0) << 4) | ((list->dy < 0) << 5) | (list->buttons & 0x07);
-	list->ps2[off + 1] = (list->dx > 127 ? 127 : (list->dx < -127 ? -127 : list->dx));
-	list->ps2[off + 2] = (list->dy > 127 ? 127 : (list->dy < -127 ? -127 : list->dy));
-	list->dx -= list->ps2[off + 1];
-	list->dy -= list->ps2[off + 2];
-	list->bufsiz = off + 3;
-
-	if (list->mode == 2) {
-		list->ps2[off + 3] = (list->dz > 7 ? 7 : (list->dz < -7 ? -7 : list->dz));
-		list->dz -= list->ps2[off + 3];
-		list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
-		list->bufsiz++;
-	} else {
-		list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
+	return delta > limit ? limit : (delta < -limit ? -limit : delta);
+}
+
+static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data)
+{
+	struct mousedev_motion *p;
+	unsigned long flags;
+
+	spin_lock_irqsave(&list->packet_lock, flags);
+	p = &list->packets[list->tail];
+
+	ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
+	ps2_data[1] = mousedev_limit_delta(p->dx, 127);
+	ps2_data[2] = mousedev_limit_delta(p->dy, 127);
+	p->dx -= ps2_data[1];
+	p->dy -= ps2_data[2];
+
+	switch (list->mode) {
+		case MOUSEDEV_EMUL_EXPS:
+			ps2_data[3] = mousedev_limit_delta(p->dz, 127);
+			p->dz -= ps2_data[3];
+			ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
+			list->bufsiz = 4;
+			break;
+
+		case MOUSEDEV_EMUL_IMPS:
+			ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
+			ps2_data[3] = mousedev_limit_delta(p->dz, 127);
+			p->dz -= ps2_data[3];
+			list->bufsiz = 4;
+			break;
+
+		case MOUSEDEV_EMUL_PS2:
+		default:
+			ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
+			p->dz = 0;
+			list->bufsiz = 3;
+			break;
 	}
 
-	if (list->mode == 1) {
-		list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz));
-		list->dz -= list->ps2[off + 3];
-		list->bufsiz++;
+	if (!p->dx && !p->dy && !p->dz) {
+		if (list->tail != list->head)
+			list->tail = (list->tail + 1) % PACKET_QUEUE_LEN;
+		if (list->tail == list->head)
+			list->ready = 0;
 	}
 
-	if (!list->dx && !list->dy && (!list->mode || !list->dz)) list->ready = 0;
-	list->buffer = list->bufsiz;
+	spin_unlock_irqrestore(&list->packet_lock, flags);
 }
 
 
@@ -384,31 +460,31 @@
 		if (c == mousedev_imex_seq[list->imexseq]) {
 			if (++list->imexseq == MOUSEDEV_SEQ_LEN) {
 				list->imexseq = 0;
-				list->mode = 2;
+				list->mode = MOUSEDEV_EMUL_EXPS;
 			}
 		} else list->imexseq = 0;
 
 		if (c == mousedev_imps_seq[list->impsseq]) {
 			if (++list->impsseq == MOUSEDEV_SEQ_LEN) {
 				list->impsseq = 0;
-				list->mode = 1;
+				list->mode = MOUSEDEV_EMUL_IMPS;
 			}
 		} else list->impsseq = 0;
 
 		list->ps2[0] = 0xfa;
-		list->bufsiz = 1;
 
 		switch (c) {
 
 			case 0xeb: /* Poll */
-				mousedev_packet(list, 1);
+				mousedev_packet(list, &list->ps2[1]);
+				list->bufsiz++; /* account for leading ACK */
 				break;
 
 			case 0xf2: /* Get ID */
 				switch (list->mode) {
-					case 0: list->ps2[1] = 0; break;
-					case 1: list->ps2[1] = 3; break;
-					case 2: list->ps2[1] = 4; break;
+					case MOUSEDEV_EMUL_PS2:  list->ps2[1] = 0; break;
+					case MOUSEDEV_EMUL_IMPS: list->ps2[1] = 3; break;
+					case MOUSEDEV_EMUL_EXPS: list->ps2[1] = 4; break;
 				}
 				list->bufsiz = 2;
 				break;
@@ -419,13 +495,15 @@
 				break;
 
 			case 0xff: /* Reset */
-				list->impsseq = 0;
-				list->imexseq = 0;
-				list->mode = 0;
-				list->ps2[1] = 0xaa;
-				list->ps2[2] = 0x00;
+				list->impsseq = list->imexseq = 0;
+				list->mode = MOUSEDEV_EMUL_PS2;
+				list->ps2[1] = 0xaa; list->ps2[2] = 0x00;
 				list->bufsiz = 3;
 				break;
+
+			default:
+				list->bufsiz = 1;
+				break;
 		}
 
 		list->buffer = list->bufsiz;
@@ -451,8 +529,10 @@
 	if (retval)
 		return retval;
 
-	if (!list->buffer && list->ready)
-		mousedev_packet(list, 0);
+	if (!list->buffer && list->ready) {
+		mousedev_packet(list, list->ps2);
+		list->buffer = list->bufsiz;
+	}
 
 	if (count > list->buffer)
 		count = list->buffer;
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/serio/i8042.c	2004-06-20 13:12:54 -07:00
@@ -1,7 +1,7 @@
 /*
  *  i8042 keyboard and mouse controller driver for Linux
  *
- *  Copyright (c) 1999-2002 Vojtech Pavlik
+ *  Copyright (c) 1999-2004 Vojtech Pavlik
  */
 
 /*
@@ -52,6 +52,10 @@
 module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
 
+extern unsigned int i8042_dmi_noloop;
+static unsigned int i8042_noloop;
+extern unsigned int i8042_dmi_noloop;
+
 __obsolete_setup("i8042_noaux");
 __obsolete_setup("i8042_nomux");
 __obsolete_setup("i8042_unlock");
@@ -95,6 +99,7 @@
 /*
  * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
  * be ready for reading values from it / writing values to it.
+ * Called always with i8042_lock held.
  */
 
 static int i8042_wait_read(void)
@@ -154,6 +159,9 @@
 	unsigned long flags;
 	int retval = 0, i = 0;
 
+	if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
+		return -1;
+
 	spin_lock_irqsave(&i8042_lock, flags);
 
 	retval = i8042_wait_write();
@@ -474,17 +482,8 @@
 	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
 		return -1;
 	param = 0xa4;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) {
-
-/*
- * Do another loop test with the 0x5a value. Doing anything else upsets
- * Profusion/ServerWorks OSB4 chipsets.
- */
-
-		param = 0x5a;
-		i8042_command(&param, I8042_CMD_AUX_LOOP);
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
 		return -1;
-	}
 
 	if (mux_version)
 		*mux_version = ~param;
@@ -677,6 +676,7 @@
 
 static int i8042_controller_init(void)
 {
+	unsigned long flags;
 
 /*
  * Test the i8042. We need to know if it thinks it's working correctly
@@ -723,12 +723,14 @@
  * Handle keylock.
  */
 
+	spin_lock_irqsave(&i8042_lock, flags);
 	if (~i8042_read_status() & I8042_STR_KEYLOCK) {
 		if (i8042_unlock)
 			i8042_ctr |= I8042_CTR_IGNKEYLOCK;
 		 else
 			printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
 	}
+	spin_unlock_irqrestore(&i8042_lock, flags);
 
 /*
  * If the chip is configured into nontranslated mode by the BIOS, don't
@@ -963,6 +965,13 @@
 
 	if (i8042_dumbkbd)
 		i8042_kbd_port.write = NULL;
+
+#ifdef __i386__
+	if (i8042_dmi_noloop) {
+		printk(KERN_INFO "i8042.c: AUX LoopBack command disabled by DMI.\n");
+		i8042_noloop = 1;
+	}
+#endif
 
 	if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
 		if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/serio/serio.c	2004-06-20 13:12:54 -07:00
@@ -1,11 +1,9 @@
 /*
- * $Id: serio.c,v 1.15 2002/01/22 21:12:03 vojtech Exp $
- *
- *  Copyright (c) 1999-2001 Vojtech Pavlik
- */
-
-/*
  *  The Serio abstraction module
+ *
+ *  Copyright (c) 1999-2004 Vojtech Pavlik
+ *  Copyright (c) 2004 Dmitry Torokhov
+ *  Copyright (c) 2003 Daniele Bellucci
  */
 
 /*
@@ -26,10 +24,6 @@
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- *
- * Changes:
- * 20 Jul. 2003    Daniele Bellucci <bellucda@tiscali.it>
- *                 Minor cleanups.
  */
 
 #include <linux/stddef.h>
@@ -61,17 +55,11 @@
 EXPORT_SYMBOL(serio_rescan);
 EXPORT_SYMBOL(serio_reconnect);
 
-struct serio_event {
-	int type;
-	struct serio *serio;
-	struct list_head node;
-};
-
-static DECLARE_MUTEX(serio_sem);
+static DECLARE_MUTEX(serio_sem);				/* protects serio_list and serio_dev_list */
 static LIST_HEAD(serio_list);
 static LIST_HEAD(serio_dev_list);
-static LIST_HEAD(serio_event_list);
-static int serio_pid;
+
+/* serio_find_dev() must be called with serio_sem down.  */
 
 static void serio_find_dev(struct serio *serio)
 {
@@ -85,34 +73,76 @@
 	}
 }
 
-#define SERIO_RESCAN		1
-#define SERIO_RECONNECT		2
-#define SERIO_REGISTER_PORT	3
-#define SERIO_UNREGISTER_PORT	4
+/*
+ * Serio event processing.
+ */
 
+struct serio_event {
+	int type;
+	struct serio *serio;
+	struct list_head node;
+};
+
+enum serio_event_type {
+	SERIO_RESCAN,
+	SERIO_RECONNECT,
+	SERIO_REGISTER_PORT,
+	SERIO_UNREGISTER_PORT,
+};
+
+static spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
+static LIST_HEAD(serio_event_list);
 static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
 static DECLARE_COMPLETION(serio_exited);
+static int serio_pid;
 
-static void serio_invalidate_pending_events(struct serio *serio)
+static void serio_queue_event(struct serio *serio, int event_type)
 {
+	unsigned long flags;
 	struct serio_event *event;
 
-	list_for_each_entry(event, &serio_event_list, node)
-		if (event->serio == serio)
-			event->serio = NULL;
+	spin_lock_irqsave(&serio_event_lock, flags);
+
+	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
+		event->type = event_type;
+		event->serio = serio;
+
+		list_add_tail(&event->node, &serio_event_list);
+		wake_up(&serio_wait);
+	}
+
+	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
-void serio_handle_events(void)
+static struct serio_event *serio_get_event(void)
 {
-	struct list_head *node, *next;
 	struct serio_event *event;
+	struct list_head *node;
+	unsigned long flags;
 
-	list_for_each_safe(node, next, &serio_event_list) {
-		event = container_of(node, struct serio_event, node);
+	spin_lock_irqsave(&serio_event_lock, flags);
+
+	if (list_empty(&serio_event_list)) {
+		spin_unlock_irqrestore(&serio_event_lock, flags);
+		return NULL;
+	}
+
+	node = serio_event_list.next;
+	event = container_of(node, struct serio_event, node);
+	list_del_init(node);
+
+	spin_unlock_irqrestore(&serio_event_lock, flags);
+
+	return event;
+}
+
+static void serio_handle_events(void)
+{
+	struct serio_event *event;
+
+	while ((event = serio_get_event())) {
 
 		down(&serio_sem);
-		if (event->serio == NULL)
-			goto event_done;
 
 		switch (event->type) {
 			case SERIO_REGISTER_PORT :
@@ -137,13 +167,32 @@
 			default:
 				break;
 		}
-event_done:
+
 		up(&serio_sem);
-		list_del_init(node);
 		kfree(event);
 	}
 }
 
+static void serio_remove_pending_events(struct serio *serio)
+{
+	struct list_head *node, *next;
+	struct serio_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio_event_lock, flags);
+
+	list_for_each_safe(node, next, &serio_event_list) {
+		event = container_of(node, struct serio_event, node);
+		if (event->serio == serio) {
+			list_del_init(node);
+			kfree(event);
+		}
+	}
+
+	spin_unlock_irqrestore(&serio_event_lock, flags);
+}
+
+
 static int serio_thread(void *nothing)
 {
 	lock_kernel();
@@ -163,18 +212,10 @@
 	complete_and_exit(&serio_exited, 0);
 }
 
-static void serio_queue_event(struct serio *serio, int event_type)
-{
-	struct serio_event *event;
-
-	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
-		event->type = event_type;
-		event->serio = serio;
 
-		list_add_tail(&event->node, &serio_event_list);
-		wake_up(&serio_wait);
-	}
-}
+/*
+ * Serio port operations
+ */
 
 void serio_rescan(struct serio *serio)
 {
@@ -186,25 +227,6 @@
 	serio_queue_event(serio, SERIO_RECONNECT);
 }
 
-irqreturn_t serio_interrupt(struct serio *serio,
-		unsigned char data, unsigned int flags, struct pt_regs *regs)
-{
-	irqreturn_t ret = IRQ_NONE;
-
-        if (serio->dev && serio->dev->interrupt) {
-                ret = serio->dev->interrupt(serio, data, flags, regs);
-	} else {
-		if (!flags) {
-			if ((serio->type == SERIO_8042 ||
-				serio->type == SERIO_8042_XL) && (data != 0xaa))
-					return ret;
-			serio_rescan(serio);
-			ret = IRQ_HANDLED;
-		}
-	}
-	return ret;
-}
-
 void serio_register_port(struct serio *serio)
 {
 	down(&serio_sem);
@@ -229,6 +251,7 @@
  */
 void __serio_register_port(struct serio *serio)
 {
+	spin_lock_init(&serio->lock);
 	list_add_tail(&serio->node, &serio_list);
 	serio_find_dev(serio);
 }
@@ -257,12 +280,16 @@
  */
 void __serio_unregister_port(struct serio *serio)
 {
-	serio_invalidate_pending_events(serio);
+	serio_remove_pending_events(serio);
 	list_del_init(&serio->node);
 	if (serio->dev && serio->dev->disconnect)
 		serio->dev->disconnect(serio);
 }
 
+/*
+ * Serio device operations
+ */
+
 void serio_register_device(struct serio_dev *dev)
 {
 	struct serio *serio;
@@ -292,9 +319,15 @@
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 int serio_open(struct serio *serio, struct serio_dev *dev)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio->lock, flags);
 	serio->dev = dev;
+	spin_unlock_irqrestore(&serio->lock, flags);
 	if (serio->open && serio->open(serio)) {
+		spin_lock_irqsave(&serio->lock, flags);
 		serio->dev = NULL;
+		spin_unlock_irqrestore(&serio->lock, flags);
 		return -1;
 	}
 	return 0;
@@ -303,9 +336,38 @@
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
+	unsigned long flags;
+
 	if (serio->close)
 		serio->close(serio);
+	spin_lock_irqsave(&serio->lock, flags);
 	serio->dev = NULL;
+	spin_unlock_irqrestore(&serio->lock, flags);
+}
+
+irqreturn_t serio_interrupt(struct serio *serio,
+		unsigned char data, unsigned int dfl, struct pt_regs *regs)
+{
+	unsigned long flags;
+	irqreturn_t ret = IRQ_NONE;
+
+	spin_lock_irqsave(&serio->lock, flags);
+
+        if (likely(serio->dev)) {
+                ret = serio->dev->interrupt(serio, data, dfl, regs);
+	} else {
+		if (!dfl) {
+			if ((serio->type != SERIO_8042 &&
+			     serio->type != SERIO_8042_XL) || (data == 0xaa)) {
+				serio_rescan(serio);
+				ret = IRQ_HANDLED;
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&serio->lock, flags);
+
+	return ret;
 }
 
 static int __init serio_init(void)
diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c
--- a/drivers/input/tsdev.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/input/tsdev.c	2004-06-20 13:12:54 -07:00
@@ -3,9 +3,17 @@
  *
  *  Copyright (c) 2001 "Crazy" james Simmons 
  *
- *  Input driver to Touchscreen device driver module.
+ *  Compaq touchscreen protocol driver. The protocol emulated by this driver
+ *  is obsolete; for new programs use the tslib library which can read directly
+ *  from evdev and perform dejittering, variance filtering and calibration -
+ *  all in user space, not at kernel level. The meaning of this driver is
+ *  to allow usage of newer input drivers with old applications that use the
+ *  old /dev/h3600_ts and /dev/h3600_tsraw devices.
  *
- *  Sponsored by Transvirtual Technology
+ *  09-Apr-2004: Andrew Zabolotny <zap@homelink.ru>
+ *      Fixed to actually work, not just output random numbers.
+ *      Added support for both h3600_ts and h3600_tsraw protocol
+ *      emulation.
  */
 
 /*
@@ -24,11 +32,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <jsimmons@transvirtual.com>.
+ * e-mail - mail your message to <jsimmons@infradead.org>.
  */
 
 #define TSDEV_MINOR_BASE 	128
 #define TSDEV_MINORS		32
+/* First 16 devices are h3600_ts compatible; second 16 are h3600_tsraw */
+#define TSDEV_MINOR_MASK	15
 #define TSDEV_BUFFER_SIZE	64
 
 #include <linux/slab.h>
@@ -52,48 +62,84 @@
 #define CONFIG_INPUT_TSDEV_SCREEN_Y	320
 #endif
 
+/* This driver emulates both protocols of the old h3600_ts and h3600_tsraw
+ * devices. The first one must output X/Y data in 'cooked' format, e.g.
+ * filtered, dejittered and calibrated. Second device just outputs raw
+ * data received from the hardware.
+ *
+ * This driver doesn't support filtering and dejittering; it supports only
+ * calibration. Filtering and dejittering must be done in the low-level
+ * driver, if needed, because it may gain additional benefits from knowing
+ * the low-level details, the nature of noise and so on.
+ *
+ * The driver precomputes a calibration matrix given the initial xres and
+ * yres values (quite innacurate for most touchscreens) that will result
+ * in a more or less expected range of output values. The driver supports
+ * the TS_SET_CAL ioctl, which will replace the calibration matrix with a
+ * new one, supposedly generated from the values taken from the raw device.
+ */
+
 MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
 MODULE_DESCRIPTION("Input driver to touchscreen converter");
 MODULE_LICENSE("GPL");
 
 static int xres = CONFIG_INPUT_TSDEV_SCREEN_X;
 module_param(xres, uint, 0);
-MODULE_PARM_DESC(xres, "Horizontal screen resolution");
+MODULE_PARM_DESC(xres, "Horizontal screen resolution (can be negative for X-mirror)");
 
 static int yres = CONFIG_INPUT_TSDEV_SCREEN_Y;
 module_param(yres, uint, 0);
-MODULE_PARM_DESC(yres, "Vertical screen resolution");
+MODULE_PARM_DESC(yres, "Vertical screen resolution (can be negative for Y-mirror)");
+
+/* From Compaq's Touch Screen Specification version 0.2 (draft) */
+struct ts_event {
+	short pressure;
+	short x;
+	short y;
+	short millisecs;
+};
+
+struct ts_calibration {
+	int xscale;
+	int xtrans;
+	int yscale;
+	int ytrans;
+	int xyswap;
+};
 
 struct tsdev {
 	int exist;
 	int open;
 	int minor;
-	char name[16];
+	char name[8];
 	wait_queue_head_t wait;
 	struct list_head list;
 	struct input_handle handle;
+	int x, y, pressure;
+	struct ts_calibration cal;
 };
 
-/* From Compaq's Touch Screen Specification version 0.2 (draft) */
-typedef struct {
-	short pressure;
-	short x;
-	short y;
-	short millisecs;
-} TS_EVENT;
-
 struct tsdev_list {
 	struct fasync_struct *fasync;
 	struct list_head node;
 	struct tsdev *tsdev;
 	int head, tail;
-	int oldx, oldy, pendown;
-	TS_EVENT event[TSDEV_BUFFER_SIZE];
+	struct ts_event event[TSDEV_BUFFER_SIZE];
+	int raw;
 };
 
+/* The following ioctl codes are defined ONLY for backward compatibility.
+ * Don't use tsdev for new developement; use the tslib library instead.
+ * Touchscreen calibration is a fully userspace task.
+ */
+/* Use 'f' as magic number */
+#define IOC_H3600_TS_MAGIC  'f'
+#define TS_GET_CAL	_IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
+#define TS_SET_CAL	_IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)
+
 static struct input_handler tsdev_handler;
 
-static struct tsdev *tsdev_table[TSDEV_MINORS];
+static struct tsdev *tsdev_table[TSDEV_MINORS/2];
 
 static int tsdev_fasync(int fd, struct file *file, int on)
 {
@@ -109,13 +155,16 @@
 	int i = iminor(inode) - TSDEV_MINOR_BASE;
 	struct tsdev_list *list;
 
-	if (i >= TSDEV_MINORS || !tsdev_table[i])
+	if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
 		return -ENODEV;
 
 	if (!(list = kmalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
 		return -ENOMEM;
 	memset(list, 0, sizeof(struct tsdev_list));
 
+	list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0;
+
+	i &= TSDEV_MINOR_MASK;
 	list->tsdev = tsdev_table[i];
 	list_add_tail(&list->node, &tsdev_table[i]->list);
 	file->private_data = list;
@@ -169,11 +218,13 @@
 	if (!list->tsdev->exist)
 		return -ENODEV;
 
-	while (list->head != list->tail && retval + sizeof(TS_EVENT) <= count) {
-		if (copy_to_user (buffer + retval, list->event + list->tail, sizeof(TS_EVENT)))
+	while (list->head != list->tail &&
+	       retval + sizeof (struct ts_event) <= count) {
+		if (copy_to_user (buffer + retval, list->event + list->tail,
+				  sizeof (struct ts_event)))
 			return -EFAULT;
 		list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1);
-		retval += sizeof(TS_EVENT);
+		retval += sizeof (struct ts_event);
 	}
 
 	return retval;
@@ -193,22 +244,27 @@
 static int tsdev_ioctl(struct inode *inode, struct file *file,
 		       unsigned int cmd, unsigned long arg)
 {
-/*
 	struct tsdev_list *list = file->private_data;
-        struct tsdev *evdev = list->tsdev;
-        struct input_dev *dev = tsdev->handle.dev;
-        int retval;
-	
+	struct tsdev *tsdev = list->tsdev;
+	int retval = 0;
+
 	switch (cmd) {
-		case HHEHE:
-			return 0;
-		case hjff:
-			return 0;
-		default:
-			return 0;
+	case TS_GET_CAL:
+		if (copy_to_user ((void *)arg, &tsdev->cal,
+				  sizeof (struct ts_calibration)))
+			retval = -EFAULT;
+		break;
+	case TS_SET_CAL:
+		if (copy_from_user (&tsdev->cal, (void *)arg,
+				    sizeof (struct ts_calibration)))
+			retval = -EFAULT;
+		break;
+	default:
+		retval = -EINVAL;
+		break;
 	}
-*/
-	return -EINVAL;
+
+	return retval;
 }
 
 struct file_operations tsdev_fops = {
@@ -227,82 +283,85 @@
 	struct tsdev *tsdev = handle->private;
 	struct tsdev_list *list;
 	struct timeval time;
-	int size;
 
-	list_for_each_entry(list, &tsdev->list, node) {
-		switch (type) {
-		case EV_ABS:
-			switch (code) {
-			case ABS_X:
-				if (!list->pendown)
-					return;
-				size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
-				if (size > 0)
-					list->oldx = ((value - handle->dev->absmin[ABS_X]) * xres / size);
-				else
-					list->oldx = ((value - handle->dev->absmin[ABS_X]));
-				break;
-			case ABS_Y:
-				if (!list->pendown)
-					return;
-				size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-				if (size > 0)
-					list->oldy = ((value - handle->dev->absmin[ABS_Y]) * yres / size);
-				else
-					list->oldy = ((value - handle->dev->absmin[ABS_Y]));
-				break;
-			case ABS_PRESSURE:
-				list->pendown = ((value > handle->dev-> absmin[ABS_PRESSURE])) ?
-				    value - handle->dev->absmin[ABS_PRESSURE] : 0;
-				break;
-			}
+	switch (type) {
+	case EV_ABS:
+		switch (code) {
+		case ABS_X:
+			tsdev->x = value;
+			break;
+		case ABS_Y:
+			tsdev->y = value;
+			break;
+		case ABS_PRESSURE:
+			if (value > handle->dev->absmax[ABS_PRESSURE])
+				value = handle->dev->absmax[ABS_PRESSURE];
+			value -= handle->dev->absmin[ABS_PRESSURE];
+			if (value < 0)
+				value = 0;
+			tsdev->pressure = value;
+			break;
+		}
+		break;
+
+	case EV_REL:
+		switch (code) {
+		case REL_X:
+			tsdev->x += value;
+			if (tsdev->x < 0)
+				tsdev->x = 0;
+			else if (tsdev->x > xres)
+				tsdev->x = xres;
+			break;
+		case REL_Y:
+			tsdev->y += value;
+			if (tsdev->y < 0)
+				tsdev->y = 0;
+			else if (tsdev->y > yres)
+				tsdev->y = yres;
 			break;
+		}
+		break;
 
-		case EV_REL:
-			switch (code) {
-			case REL_X:
-				if (!list->pendown)
-					return;
-				list->oldx += value;
-				if (list->oldx < 0)
-					list->oldx = 0;
-				else if (list->oldx > xres)
-					list->oldx = xres;
+	case EV_KEY:
+		if (code == BTN_TOUCH || code == BTN_MOUSE) {
+			switch (value) {
+			case 0:
+				tsdev->pressure = 0;
 				break;
-			case REL_Y:
-				if (!list->pendown)
-					return;
-				list->oldy += value;
-				if (list->oldy < 0)
-					list->oldy = 0;
-				else if (list->oldy > xres)
-					list->oldy = xres;
+			case 1:
+				if (!tsdev->pressure)
+					tsdev->pressure = 1;
 				break;
 			}
-			break;
-
-		case EV_KEY:
-			if (code == BTN_TOUCH || code == BTN_MOUSE) {
-				switch (value) {
-				case 0:
-					list->pendown = 0;
-					break;
-				case 1:
-					if (!list->pendown)
-						list->pendown = 1;
-					break;
-				case 2:
-					return;
-				}
-			} else
-				return;
-			break;
 		}
+		break;
+	}
+
+	if (type != EV_SYN || code != SYN_REPORT)
+		return;
+
+	list_for_each_entry(list, &tsdev->list, node) {
+		int x, y, tmp;
+
 		do_gettimeofday(&time);
 		list->event[list->head].millisecs = time.tv_usec / 100;
-		list->event[list->head].pressure = list->pendown;
-		list->event[list->head].x = list->oldx;
-		list->event[list->head].y = list->oldy;
+		list->event[list->head].pressure = tsdev->pressure;
+
+		x = tsdev->x;
+		y = tsdev->y;
+
+		/* Calibration */
+		if (!list->raw) {
+			x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans;
+			y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans;
+			if (tsdev->cal.xyswap) {
+				tmp = x; x = y; y = tmp;
+			}
+		}
+
+		list->event[list->head].x = x;
+		list->event[list->head].y = y;
 		list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1);
 		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 	}
@@ -314,11 +373,11 @@
 					  struct input_device_id *id)
 {
 	struct tsdev *tsdev;
-	int minor;
+	int minor, delta;
 
-	for (minor = 0; minor < TSDEV_MINORS && tsdev_table[minor];
+	for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor];
 	     minor++);
-	if (minor == TSDEV_MINORS) {
+	if (minor >= TSDEV_MINORS/2) {
 		printk(KERN_ERR
 		       "tsdev: You have way too many touchscreens\n");
 		return NULL;
@@ -340,10 +399,25 @@
 	tsdev->handle.handler = handler;
 	tsdev->handle.private = tsdev;
 
+	/* Precompute the rough calibration matrix */
+	delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
+	if (delta == 0)
+		delta = 1;
+	tsdev->cal.xscale = (xres << 8) / delta;
+	tsdev->cal.xtrans = - ((dev->absmin [ABS_X] * tsdev->cal.xscale) >> 8);
+
+	delta = dev->absmax [ABS_Y] - dev->absmin [ABS_Y] + 1;
+	if (delta == 0)
+		delta = 1;
+	tsdev->cal.yscale = (yres << 8) / delta;
+	tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
+
 	tsdev_table[minor] = tsdev;
-	
+
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
+	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
+			S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
 	class_simple_device_add(input_class, 
 				MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
 				dev->dev, "ts%d", minor);
@@ -362,6 +436,7 @@
 		wake_up_interruptible(&tsdev->wait);
 	} else
 		tsdev_free(tsdev);
+	devfs_remove("input/tsraw%d", tsdev->minor);
 }
 
 static struct input_device_id tsdev_ids[] = {
@@ -378,6 +453,12 @@
 	      .keybit	= { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
 	      .absbit	= { BIT(ABS_X) | BIT(ABS_Y) },
 	 },/* A tablet like device, at least touch detection, two absolute axes */
+
+	{
+	      .flags	= INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+	      .evbit	= { BIT(EV_ABS) },
+	      .absbit	= { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
+	 },/* A tablet like device with several gradations of pressure */
 
 	{},/* Terminating entry */
 };
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	2004-06-20 13:12:54 -07:00
+++ b/drivers/usb/input/hiddev.c	2004-06-20 13:12:54 -07:00
@@ -639,16 +639,22 @@
 				goto inval;
 
 			field = report->field[uref->field_index];
-			if (uref->usage_index >= field->maxusage)
-				goto inval;
 
-			if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
-				if (uref_multi->num_values >= HID_MAX_USAGES || 
-				    uref->usage_index >= field->maxusage || 
-				   (uref->usage_index + uref_multi->num_values) >= field->maxusage)
+			if (cmd == HIDIOCGCOLLECTIONINDEX) {
+				if (uref->usage_index >= field->maxusage)
 					goto inval;
+			} else if (uref->usage_index >= field->report_count)
+				goto inval;
+
+			else if ((cmd == HIDIOCGUSAGES ||
+				  cmd == HIDIOCSUSAGES) &&
+				 (uref->usage_index + uref_multi->num_values >=
+				  field->report_count ||
+				  uref->usage_index + uref_multi->num_values <
+				  uref->usage_index))
+				goto inval;
+
 			}
-		}
 
 		switch (cmd) {
 			case HIDIOCGUSAGE:
diff -Nru a/fs/compat_ioctl.c b/fs/compat_ioctl.c
--- a/fs/compat_ioctl.c	2004-06-20 13:12:54 -07:00
+++ b/fs/compat_ioctl.c	2004-06-20 13:12:54 -07:00
@@ -115,6 +115,8 @@
 #include <linux/filter.h>
 #include <linux/msdos_fs.h>
 
+#include <linux/hiddev.h>
+
 #undef INCLUDES
 #endif
 
diff -Nru a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
--- a/include/linux/compat_ioctl.h	2004-06-20 13:12:54 -07:00
+++ b/include/linux/compat_ioctl.h	2004-06-20 13:12:54 -07:00
@@ -728,3 +728,20 @@
 COMPATIBLE_IOCTL(SIOCGIWRETRY)
 COMPATIBLE_IOCTL(SIOCSIWPOWER)
 COMPATIBLE_IOCTL(SIOCGIWPOWER)
+/* hiddev */
+COMPATIBLE_IOCTL(HIDIOCGVERSION)
+COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
+COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
+COMPATIBLE_IOCTL(HIDIOCGSTRING)
+COMPATIBLE_IOCTL(HIDIOCINITREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORT)
+COMPATIBLE_IOCTL(HIDIOCSREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
+COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
+COMPATIBLE_IOCTL(HIDIOCGUSAGE)
+COMPATIBLE_IOCTL(HIDIOCSUSAGE)
+COMPATIBLE_IOCTL(HIDIOCGUCODE)
+COMPATIBLE_IOCTL(HIDIOCGFLAG)
+COMPATIBLE_IOCTL(HIDIOCSFLAG)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
diff -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h
--- a/include/linux/hiddev.h	2004-06-20 13:12:54 -07:00
+++ b/include/linux/hiddev.h	2004-06-20 13:12:54 -07:00
@@ -128,10 +128,11 @@
 
 /* hiddev_usage_ref_multi is used for sending multiple bytes to a control.
  * It really manifests itself as setting the value of consecutive usages */
+#define HID_MAX_MULTI_USAGES 1024
 struct hiddev_usage_ref_multi {
 	struct hiddev_usage_ref uref;
 	__u32 num_values;
-	__s32 values[HID_MAX_USAGES];
+	__s32 values[HID_MAX_MULTI_USAGES];
 };
 
 /* FIELD_INDEX_NONE is returned in read() data from the kernel when flags
@@ -211,6 +212,11 @@
 /*
  * In-kernel definitions.
  */
+
+struct hid_device;
+struct hid_usage;
+struct hid_field;
+struct hid_report;
 
 #ifdef CONFIG_USB_HIDDEV
 int hiddev_connect(struct hid_device *);
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	2004-06-20 13:12:54 -07:00
+++ b/include/linux/input.h	2004-06-20 13:12:54 -07:00
@@ -527,6 +527,8 @@
 #define MSC_SERIAL		0x00
 #define MSC_PULSELED		0x01
 #define MSC_GESTURE		0x02
+#define MSC_RAW			0x03
+#define MSC_SCAN		0x04
 #define MSC_MAX			0x07
 
 /*
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2004-06-20 13:12:54 -07:00
+++ b/include/linux/serio.h	2004-06-20 13:12:54 -07:00
@@ -17,6 +17,7 @@
 #ifdef __KERNEL__
 
 #include <linux/list.h>
+#include <linux/spinlock.h>
 
 struct serio {
 	void *private;
@@ -32,11 +33,13 @@
 	unsigned long type;
 	unsigned long event;
 
+	spinlock_t lock;
+
 	int (*write)(struct serio *, unsigned char);
 	int (*open)(struct serio *);
 	void (*close)(struct serio *);
 
-	struct serio_dev *dev;
+	struct serio_dev *dev; /* Accessed from interrupt, writes must be protected by serio_lock */
 
 	struct list_head node;
 };
