bk://kernel.bkbits.net/vojtech/input
vojtech@suse.cz|ChangeSet|20040430152000|40922 vojtech

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/04/30 10:59:00-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# Documentation/kernel-parameters.txt
#   2004/04/30 10:58:57-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/30 17:20:00+02:00 vojtech@suse.cz 
#   Merge bk://dtor.bkbits.net/input into suse.cz:/home/vojtech/bk/input-dt
# 
# Documentation/kernel-parameters.txt
#   2004/04/30 17:19:57+02:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/27 01:12:57-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# Documentation/kernel-parameters.txt
#   2004/04/27 01:12:54-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/23 12:45:46-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/04/23 12:45:44-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/23 02:51:39-05:00 dtor_core@ameritech.net 
#   Input: - move set_abs_params from synaptics driver to input and
#            rename to input_set_abs_params
#          - convert input_report_* macros into inline functions
#          - make use of set_abs_params in touchscreen drivers
# 
# include/linux/input.h
#   2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +50 -9
#   Move set_abs_params from synaptics; convert input_report* macros
#   into inline fucntions
# 
# drivers/input/touchscreen/h3600_ts_input.c
#   2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +6 -8
#   Use input_set_abs_params to set device properties
# 
# drivers/input/touchscreen/gunze.c
#   2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +2 -4
#   Use input_set_abs_params to set device properties
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +3 -14
#   Remove set_abs_params; use input_set_abs_params instead
# 
# ChangeSet
#   2004/04/23 02:50:49-05:00 dtor_core@ameritech.net 
#   Input: trailing whitespace fixes
# 
# include/linux/input.h
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +1 -1
#   Trailing whitespace fixes
# 
# drivers/input/touchscreen/h3600_ts_input.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +33 -33
#   Trailing whitespace fixes
# 
# drivers/input/touchscreen/gunze.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +1 -1
#   Trailing whitespace fixes
# 
# drivers/input/misc/uinput.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +25 -25
#   Trailing whitespace fixes
# 
# drivers/input/misc/sparcspkr.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +4 -4
#   Trailing whitespace fixes
# 
# drivers/input/misc/pcspkr.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +2 -2
#   Trailing whitespace fixes
# 
# drivers/input/misc/98spkr.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +2 -2
#   Trailing whitespace fixes
# 
# drivers/input/input.c
#   2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +20 -20
#   Trailing whitespace fixes
# 
# ChangeSet
#   2004/04/23 02:50:09-05:00 dtor_core@ameritech.net 
#   Input: make serio open and close methods optional
# 
# drivers/input/serio/serport.c
#   2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +2 -8
#   Remove serio open method as it is not needed anymore.
# 
# drivers/input/serio/serio.c
#   2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +3 -2
#   Make serio open and close methods optional.
# 
# drivers/input/serio/q40kbd.c
#   2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +0 -11
#   Remove serio open and close methods as they are not needed anymore.
# 
# drivers/input/serio/parkbd.c
#   2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +0 -11
#   Remove serio open and close methods as they are not needed anymore.
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +0 -11
#   Remove pass-through open and close methods as they are not needed anymore.
# 
# ChangeSet
#   2004/04/23 02:48:40-05:00 dtor_core@ameritech.net 
#   Input: serio trailing whitespace fixes
# 
# drivers/input/serio/serio.c
#   2004/04/22 21:48:17-05:00 dtor_core@ameritech.net +6 -6
#   Trailing whitespace fixes
# 
# ChangeSet
#   2004/04/23 02:46:06-05:00 dtor_core@ameritech.net 
#   Input: allow disabling legacy psaux device even for non-embedded systems
# 
# drivers/input/Kconfig
#   2004/04/22 21:45:47-05:00 dtor_core@ameritech.net +8 -1
#   Allow disabling legacy psaux device even for non-embedded systems
# 
# ChangeSet
#   2004/04/23 02:45:14-05:00 dtor_core@ameritech.net 
#   Input: do not modify device's properties when probing for protocol
#          extensions on reconnect as it may interfere with reconnect
#          process
# 
# drivers/input/mouse/psmouse-base.c
#   2004/04/22 21:44:58-05:00 dtor_core@ameritech.net +43 -35
#   Do not alter device's properties on reconnect
# 
# drivers/input/mouse/logips2pp.h
#   2004/04/22 21:44:58-05:00 dtor_core@ameritech.net +3 -2
#   Allow t specify whether the init routine should set device's
#   properties.
# 
# drivers/input/mouse/logips2pp.c
#   2004/04/22 21:44:58-05:00 dtor_core@ameritech.net +91 -77
#   Split protocol probing from setting device's properties
# 
# ChangeSet
#   2004/04/23 02:44:24-05:00 dtor_core@ameritech.net 
#   Input: add psmouse_sliced_command (passes extended commands encoded
#          with 0xE8 to the mouse) and use it in Synaptics and Logitech
#          drivers
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +3 -25
#   Use psmouse_sliced_command instead of local implementation
# 
# drivers/input/mouse/psmouse.h
#   2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +1 -0
#   Add psmouse_sliced_command
# 
# drivers/input/mouse/psmouse-base.c
#   2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +24 -0
#   Add psmouse_sliced_command
# 
# drivers/input/mouse/logips2pp.c
#   2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +1 -11
#   Use psmouse_sliced_command instead of local implementation
# 
# ChangeSet
#   2004/04/23 02:43:45-05:00 dtor_core@ameritech.net 
#   Input: add protocol_handler to psmouse structure to ease adding
#          new protocols to psmouse module
# 
# drivers/input/mouse/synaptics.h
#   2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +0 -1
#   Add protocol_handler to psmouse structure
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +144 -141
#   Add protocol_handler to psmouse structure
# 
# drivers/input/mouse/psmouse.h
#   2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +1 -0
#   Add protocol_handler to psmouse structure
# 
# drivers/input/mouse/psmouse-base.c
#   2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +2 -2
#   Add protocol handler to psmouse structure
# 
# ChangeSet
#   2004/04/23 02:42:57-05:00 dtor_core@ameritech.net 
#   Input: move "reconnect after so many errors" handling from synaptics driver
#          to psmouse so it can be used by other PS/2 protcol drivers (but so far
#          only synaptics knows how to validate incoming data)
# 
# drivers/input/mouse/synaptics.h
#   2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +1 -2
#   out_of_sync field moved to psmouse structure.
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +8 -16
#   Do not issue reconnect request after errors, just let caller
#   know whether the byte was good or bad and let it decide what
#   to do.
# 
# drivers/input/mouse/psmouse.h
#   2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +8 -1
#   Add out_of_sync to psmouse, define psmouse_ret_t describing
#   received data.
# 
# drivers/input/mouse/psmouse-base.c
#   2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +43 -18
#   If protocol handler returns that data is bad too many times issue reconnect
#   request for the device in question.
# 
# Documentation/kernel-parameters.txt
#   2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +2 -2
#   Clarify psmouse.resetafter comment
# 
# ChangeSet
#   2004/04/23 02:41:59-05:00 dtor_core@ameritech.net 
#   Input: when getting a new device announce (0xAA 0x00) in psmouse
#          try reconnecting instead of rescanning to preserve (if possible)
#          the same input device.
# 
# drivers/input/mouse/psmouse-base.c
#   2004/04/22 21:41:43-05:00 dtor_core@ameritech.net +1 -1
#   When getting 0xAA 0x00 try reconnecting instead of rescanning to
#   preserve (if possible) the same input device.
# 
# ChangeSet
#   2004/04/23 02:40:48-05:00 dtor_core@ameritech.net 
#   Input: Do not generate events from atkbd until keyboard is completely
#          initialized. It should suppress messages about suprious NAKs
#          when controller's timeout is longer than one in atkbd
# 
# drivers/input/keyboard/atkbd.c
#   2004/04/22 21:40:33-05:00 dtor_core@ameritech.net +6 -0
#   Do not generate events until keyboard is completely initialized
# 
# ChangeSet
#   2004/04/23 02:40:08-05:00 dtor_core@ameritech.net 
#   Input: remove unneeded fields in atkbd structure, convert to bitfields
# 
# drivers/input/keyboard/atkbd.c
#   2004/04/22 21:39:42-05:00 dtor_core@ameritech.net +11 -11
#   Remove unneeded fields in atkbd structure, convert to bitfields
# 
# ChangeSet
#   2004/04/23 02:39:09-05:00 dtor_core@ameritech.net 
#   Input: fix trailing whitespace in atkbd
# 
# drivers/input/keyboard/atkbd.c
#   2004/04/22 21:38:31-05:00 dtor_core@ameritech.net +2 -2
#   Fix trailing whotespace
# 
# ChangeSet
#   2004/04/23 02:37:43-05:00 dtor_core@ameritech.net 
#   Input: Change spurious ACK warning in atkbd to soften accusation
#          against XFree86
# 
# drivers/input/keyboard/atkbd.c
#   2004/04/22 21:37:01-05:00 dtor_core@ameritech.net +14 -9
#   Change spurious ACK warning so we don't accuse XFree86 that strongly
# 
# ChangeSet
#   2004/04/23 02:33:04-05:00 dtor_core@ameritech.net 
#   Input: pass maximum allowed protocol to psmouse_extensions instead of
#          accessing psmouse_max_proto directly allowing to avoid changing
#          the global parameter when synaptics initialization fails
# 
# drivers/input/mouse/psmouse-base.c
#   2004/04/22 21:32:48-05:00 dtor_core@ameritech.net +9 -10
#   Pass maximum allowed protocol to psmouse_extensions instead of
#   accessing psmouse_max_proto directly allowing to avoid changing
#   the global parameter when synaptics initialization fails
# 
# ChangeSet
#   2004/04/23 02:32:22-05:00 dtor_core@ameritech.net 
#   Input: support Synaptics touchpads that have separate middle button
# 
# drivers/input/mouse/synaptics.h
#   2004/04/22 21:31:47-05:00 dtor_core@ameritech.net +2 -0
#   Add middle button data
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:31:47-05:00 dtor_core@ameritech.net +11 -0
#   Support touchpads that have separate middle pbutton
# 
# ChangeSet
#   2004/04/23 02:28:25-05:00 dtor_core@ameritech.net 
#   Input: synaptics driver cleanup
#          - pack all button data in 2 bytes instead of 48
#          - adjust the way we extract button data
#          - query extended capabilities if SYN_EXT_CAP_REQUESTS >= 1
#            (was == 1) according to Synaptics' addendum to the interfacing
#            guide
#          - do not announce or report BTN_BACK/BTN_FORWARD unless touchpad
#            has SYN_CAP_FOUR_BUTTON in its capability flags
# 
# drivers/input/mouse/synaptics.h
#   2004/04/22 21:17:06-05:00 dtor_core@ameritech.net +6 -13
#   Pack all button data in 2 bytes instead of 48
# 
# drivers/input/mouse/synaptics.c
#   2004/04/22 21:17:06-05:00 dtor_core@ameritech.net +59 -78
#   - adjust the way we extract button data
#   - query extended capabilities if SYN_EXT_CAP_REQUESTS >= 1
#     (was == 1) according to Synaptics' addendum to the interfacing
#     guide
#   - do not announce or report BTN_BACK/BTN_FORWARD unless touchpad
#     has SYN_CAP_FOUR_BUTTON in its capability flags
# 
# ChangeSet
#   2004/04/21 21:59:48-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/04/21 21:59:45-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/19 19:33:52-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/04/19 19:33:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/char/Kconfig
#   2004/04/19 19:33:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/05 17:39:48+02:00 vojtech@suse.cz 
#   input: Fix emulation of mouse reset (0xff) command.
# 
# drivers/input/mousedev.c
#   2004/04/05 17:39:39+02:00 vojtech@suse.cz +3 -3
#   input: Fix emulation of mouse reset (0xff) command.
# 
# ChangeSet
#   2004/04/01 15:09:02-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/04/01 15:08:59-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/26 16:27:05+01:00 vojtech@suse.cz 
#   input: Profusion/ServerWorks chipset workaround in i8042.c for Ingo Molnar.
# 
# drivers/input/serio/i8042.c
#   2004/03/26 16:27:00+01:00 vojtech@suse.cz +10 -1
#   input: Profusion/ServerWorks chipset workaround in i8042.c for Ingo Molnar.
# 
# ChangeSet
#   2004/03/24 12:34:31+01:00 vojtech@suse.cz 
#   Merge suse.cz:/data/bk/linus into suse.cz:/data/bk/input
# 
# drivers/input/serio/i8042.c
#   2004/03/24 12:34:28+01:00 vojtech@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/24 02:40:26-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# Documentation/kernel-parameters.txt
#   2004/03/24 02:40:23-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/23 03:06:16-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/input/serio/i8042.c
#   2004/03/23 03:06:13-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/22 13:30:28-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# drivers/input/serio/i8042.c
#   2004/03/22 13:30:25-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/19 14:56:45+01:00 vojtech@suse.cz 
#   input: Chips passing MUX detection incorrectly due to USB Legacy support
#          report MUX version 10.12, not 12.10. Fixed.
# 
# drivers/input/serio/i8042.c
#   2004/03/19 14:56:40+01:00 vojtech@suse.cz +2 -2
#   input: Chips passing MUX detection incorrectly due to USB Legacy support
#          report MUX version 10.12, not 12.10. Fixed.
# 
# ChangeSet
#   2004/03/16 12:44:52-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/03/16 12:44:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/char/Kconfig
#   2004/03/16 12:44:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/kernel-parameters.txt
#   2004/03/16 12:44:36-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/14 10:50:14-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/03/14 10:50:00-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/kernel-parameters.txt
#   2004/03/14 10:50:00-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/12 10:44:04-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input
# 
# drivers/char/Kconfig
#   2004/03/12 10:43:50-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/12 00:49:27-08:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into bix.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/03/12 00:49:07-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/10 10:36:24-08:00 akpm@mnm.(none) 
#   Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-input
# 
# init/main.c
#   2004/03/10 10:36:17-08:00 akpm@mnm.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/08 22:31:40-08:00 akpm@mnm.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into mnm.(none):/usr/src/bk-input
# 
# Documentation/kernel-parameters.txt
#   2004/03/08 22:31:33-08:00 akpm@mnm.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/06 12:55:28-08:00 akpm@mnm.(none) 
#   Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-input
# 
# Documentation/kernel-parameters.txt
#   2004/03/06 12:55:22-08:00 akpm@mnm.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/03 14:17:29-08:00 akpm@mnm.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into mnm.(none):/usr/src/bk-input
# 
# drivers/input/serio/i8042.c
#   2004/03/03 14:17:23-08:00 akpm@mnm.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/03 02:22:06-08:00 akpm@mnm.(none) 
#   Merge bk://kernel.bkbits.net/vojtech/input
#   into mnm.(none):/usr/src/bk-input
# 
# drivers/input/serio/i8042.c
#   2004/03/03 02:22:00-08:00 akpm@mnm.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/03/02 22:13:49-08:00 akpm@mnm.(none) 
#   Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-input
# 
# drivers/input/serio/i8042.c
#   2004/03/02 22:13:42-08:00 akpm@mnm.(none) +0 -0
#   Auto merged
# 
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	Tue May  4 22:10:38 2004
+++ b/Documentation/kernel-parameters.txt	Tue May  4 22:10:38 2004
@@ -890,8 +890,8 @@
 	psmouse.rate=	[HW,MOUSE] Set desired mouse report rate, in reports
 			per second.
 	psmouse.resetafter=
-			[HW,MOUSE] Try to reset Synaptics Touchpad after so many
-			bad packets (0 = never).
+			[HW,MOUSE] Try to reset the device after so many bad packets
+			(0 = never).
 	psmouse.resolution=
 			[HW,MOUSE] Set desired mouse resolution, in dpi.
 	psmouse.smartscroll=
diff -Nru a/drivers/input/Kconfig b/drivers/input/Kconfig
--- a/drivers/input/Kconfig	Tue May  4 22:10:38 2004
+++ b/drivers/input/Kconfig	Tue May  4 22:10:38 2004
@@ -41,9 +41,16 @@
 	  module will be called mousedev.
 
 config INPUT_MOUSEDEV_PSAUX
-	bool "Provide legacy /dev/psaux device" if EMBEDDED
+	bool "Provide legacy /dev/psaux device"
 	default y
 	depends on INPUT_MOUSEDEV
+	---help---
+	  Say Y here if you want your mouse also be accessible as char device
+	  10:1 - /dev/psaux. The data available through /dev/psaux is exactly
+	  the same as the data from /dev/input/mice.
+
+	  If unsure, say Y.
+
 
 config INPUT_MOUSEDEV_SCREEN_X
 	int "Horizontal screen resolution"
diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/input.c	Tue May  4 22:10:38 2004
@@ -106,7 +106,7 @@
 			}
 
 			break;
-		
+
 		case EV_ABS:
 
 			if (code > ABS_MAX || !test_bit(code, dev->absbit))
@@ -144,27 +144,27 @@
 			if (code > MSC_MAX || !test_bit(code, dev->mscbit))
 				return;
 
-			if (dev->event) dev->event(dev, type, code, value);	
-	
+			if (dev->event) dev->event(dev, type, code, value);
+
 			break;
 
 		case EV_LED:
-	
+
 			if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
 				return;
 
 			change_bit(code, dev->led);
-			if (dev->event) dev->event(dev, type, code, value);	
-	
+			if (dev->event) dev->event(dev, type, code, value);
+
 			break;
 
 		case EV_SND:
-	
+
 			if (code > SND_MAX || !test_bit(code, dev->sndbit))
 				return;
 
-			if (dev->event) dev->event(dev, type, code, value);	
-	
+			if (dev->event) dev->event(dev, type, code, value);
+
 			break;
 
 		case EV_REP:
@@ -181,7 +181,7 @@
 			break;
 	}
 
-	if (type != EV_SYN) 
+	if (type != EV_SYN)
 		dev->sync = 0;
 
 	if (dev->grab)
@@ -282,11 +282,11 @@
 		if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
 			if (id->id.vendor != dev->id.vendor)
 				continue;
-	
+
 		if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
 			if (id->id.product != dev->id.product)
 				continue;
-		
+
 		if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
 			if (id->id.version != dev->id.version)
 				continue;
@@ -351,11 +351,11 @@
 	}
 	if (in_interrupt()) {
 		printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
-		return; 
+		return;
 	}
 	if (!current->fs->root) {
 		printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
-		return; 
+		return;
 	}
 	if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
 		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
@@ -381,17 +381,17 @@
 
 	envp[i++] = scratch;
 	scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
-		dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; 
-	
+		dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
+
 	if (dev->name) {
 		envp[i++] = scratch;
-		scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; 
+		scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
 	}
 
 	if (dev->phys) {
 		envp[i++] = scratch;
-		scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1; 
-	}	
+		scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
+	}
 
 	SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
 	SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
@@ -506,7 +506,7 @@
 		input_table[handler->minor >> 5] = handler;
 
 	list_add_tail(&handler->node, &input_handler_list);
-	
+
 	list_for_each_entry(dev, &input_dev_list, node)
 		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
 			if ((id = input_match_device(handler->id_table, dev)))
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/keyboard/atkbd.c	Tue May  4 22:10:38 2004
@@ -26,7 +26,6 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/workqueue.h>
-#include <linux/timer.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
@@ -173,22 +172,24 @@
 	unsigned char keycode[512];
 	struct input_dev dev;
 	struct serio *serio;
-	struct timer_list timer;
+
 	char name[64];
 	char phys[32];
+	unsigned short id;
+	unsigned char set;
+	unsigned int translated:1;
+	unsigned int extra:1;
+	unsigned int write:1;
+
 	unsigned char cmdbuf[4];
 	unsigned char cmdcnt;
-	unsigned char set;
-	unsigned char extra;
-	unsigned char release;
-	int lastkey;
 	volatile signed char ack;
 	unsigned char emul;
-	unsigned short id;
-	unsigned char write;
-	unsigned char translated;
-	unsigned char resend;
-	unsigned char bat_xl;
+	unsigned int resend:1;
+	unsigned int release:1;
+	unsigned int bat_xl:1;
+	unsigned int enabled:1;
+
 	unsigned int last;
 	unsigned long time;
 };
@@ -248,6 +249,9 @@
 		goto out;
 	}
 
+	if (!atkbd->enabled)
+		goto out;
+
 	if (atkbd->translated) {
 
 		if (atkbd->emul ||
@@ -300,15 +304,20 @@
 		case ATKBD_KEY_NULL:
 			break;
 		case ATKBD_KEY_UNKNOWN:
-			printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
-				atkbd->release ? "released" : "pressed",
-				atkbd->translated ? "translated" : "raw",
-				atkbd->set, code, serio->phys);
-			if (atkbd->translated && atkbd->set == 2 && code == 0x7a)
-				printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access"
-					" hardware directly.\n");
-			else
-				printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n",						code & 0x80 ? "e0" : "", code & 0x7f);
+			if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
+				printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
+				       "like XFree86, might be trying access hardware directly.\n",
+				       data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+			} else {
+				printk(KERN_WARNING "atkbd.c: Unknown key %s "
+				       "(%s set %d, code %#x on %s).\n",
+				       atkbd->release ? "released" : "pressed",
+				       atkbd->translated ? "translated" : "raw",
+				       atkbd->set, code, serio->phys);
+				printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' "
+				       "to make it known.\n",
+				       code & 0x80 ? "e0" : "", code & 0x7f);
+			}
 			break;
 		case ATKBD_SCR_1:
 			scroll = 1 - atkbd->release * 2;
@@ -745,6 +754,8 @@
 		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");
@@ -809,12 +820,12 @@
 		param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
 		         | (test_bit(LED_NUML,    atkbd->dev.led) ? 2 : 0)
  		         | (test_bit(LED_CAPSL,   atkbd->dev.led) ? 4 : 0);
-		
+
 		if (atkbd_probe(atkbd))
 			return -1;
 		if (atkbd->set != atkbd_set_3(atkbd))
 			return -1;
-		
+
 		atkbd_enable(atkbd);
 
 		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
diff -Nru a/drivers/input/misc/98spkr.c b/drivers/input/misc/98spkr.c
--- a/drivers/input/misc/98spkr.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/misc/98spkr.c	Tue May  4 22:10:38 2004
@@ -41,11 +41,11 @@
 		case SND_BELL: if (value) value = 1000;
 		case SND_TONE: break;
 		default: return -1;
-	} 
+	}
 
 	if (value > 20 && value < 32767)
 		count = CLOCK_TICK_RATE / value;
-	
+
 	spin_lock_irqsave(&i8253_beep_lock, flags);
 
 	if (count) {
diff -Nru a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
--- a/drivers/input/misc/pcspkr.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/misc/pcspkr.c	Tue May  4 22:10:38 2004
@@ -40,11 +40,11 @@
 		case SND_BELL: if (value) value = 1000;
 		case SND_TONE: break;
 		default: return -1;
-	} 
+	}
 
 	if (value > 20 && value < 32767)
 		count = CLOCK_TICK_RATE / value;
-	
+
 	spin_lock_irqsave(&i8253_beep_lock, flags);
 
 	if (count) {
diff -Nru a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
--- a/drivers/input/misc/sparcspkr.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/misc/sparcspkr.c	Tue May  4 22:10:38 2004
@@ -53,11 +53,11 @@
 		case SND_BELL: if (value) value = 1000;
 		case SND_TONE: break;
 		default: return -1;
-	} 
+	}
 
 	if (value > 20 && value < 32767)
 		count = 1193182 / value;
-	
+
 	spin_lock_irqsave(&beep_lock, flags);
 
 	/* EBUS speaker only has on/off state, the frequency does not
@@ -108,11 +108,11 @@
 		case SND_BELL: if (value) value = 1000;
 		case SND_TONE: break;
 		default: return -1;
-	} 
+	}
 
 	if (value > 20 && value < 32767)
 		count = 1193182 / value;
-	
+
 	spin_lock_irqsave(&beep_lock, flags);
 
 	if (count) {
diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- a/drivers/input/misc/uinput.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/misc/uinput.c	Tue May  4 22:10:38 2004
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
- * 
+ *
  * Changes/Revisions:
  *	0.1	20/06/2002
  *		- first public version
@@ -68,7 +68,7 @@
 static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
 {
 	return 0;
-}					
+}
 
 static int uinput_create_device(struct uinput_device *udev)
 {
@@ -123,7 +123,7 @@
 	memset(newinput, 0, sizeof(struct input_dev));
 
 	newdev->dev = newinput;
-	
+
 	file->private_data = newdev;
 
 	return 0;
@@ -137,16 +137,16 @@
 {
 	unsigned int cnt;
 	int retval = 0;
-	
+
 	for (cnt = 0; cnt < ABS_MAX; cnt++) {
-		if (!test_bit(cnt, dev->absbit)) 
+		if (!test_bit(cnt, dev->absbit))
 			continue;
-		
+
 		if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
 		    (dev->absmax[cnt] <= dev->absmin[cnt])) {
-			printk(KERN_DEBUG 
+			printk(KERN_DEBUG
 				"%s: invalid abs[%02x] min:%d max:%d\n",
-				UINPUT_NAME, cnt, 
+				UINPUT_NAME, cnt,
 				dev->absmin[cnt], dev->absmax[cnt]);
 			retval = -EINVAL;
 			break;
@@ -154,7 +154,7 @@
 
 		if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
 		    (dev->absflat[cnt] > dev->absmax[cnt])) {
-			printk(KERN_DEBUG 
+			printk(KERN_DEBUG
 				"%s: absflat[%02x] out of range: %d "
 				"(min:%d/max:%d)\n",
 				UINPUT_NAME, cnt, dev->absflat[cnt],
@@ -190,7 +190,7 @@
 		goto exit;
 	}
 
-	if (NULL != dev->name) 
+	if (NULL != dev->name)
 		kfree(dev->name);
 
 	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
@@ -229,7 +229,7 @@
 static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
 {
 	struct uinput_device	*udev = file->private_data;
-	
+
 	if (test_bit(UIST_CREATED, &(udev->state))) {
 		struct input_event	ev;
 
@@ -247,7 +247,7 @@
 {
 	struct uinput_device *udev = file->private_data;
 	int retval = 0;
-	
+
 	if (!test_bit(UIST_CREATED, &(udev->state)))
 		return -ENODEV;
 
@@ -255,16 +255,16 @@
 		return -EAGAIN;
 
 	retval = wait_event_interruptible(udev->waitq,
-			(udev->head != udev->tail) || 
+			(udev->head != udev->tail) ||
 			!test_bit(UIST_CREATED, &(udev->state)));
-	
+
 	if (retval)
 		return retval;
 
 	if (!test_bit(UIST_CREATED, &(udev->state)))
 		return -ENODEV;
 
-	while ((udev->head != udev->tail) && 
+	while ((udev->head != udev->tail) &&
 	    (retval + sizeof(struct input_event) <= count)) {
 		if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
 		    sizeof(struct input_event))) return -EFAULT;
@@ -284,7 +284,7 @@
 	if (udev->head != udev->tail)
 		return POLLIN | POLLRDNORM;
 
-	return 0;			
+	return 0;
 }
 
 static int uinput_burn_device(struct uinput_device *udev)
@@ -318,7 +318,7 @@
 		case UI_DEV_CREATE:
 			retval = uinput_create_device(udev);
 			break;
-			
+
 		case UI_DEV_DESTROY:
 			retval = uinput_destroy_device(udev);
 			break;
@@ -330,7 +330,7 @@
 			}
 			set_bit(arg, udev->dev->evbit);
 			break;
-			
+
 		case UI_SET_KEYBIT:
 			if (arg > KEY_MAX) {
 				retval = -EINVAL;
@@ -338,7 +338,7 @@
 			}
 			set_bit(arg, udev->dev->keybit);
 			break;
-			
+
 		case UI_SET_RELBIT:
 			if (arg > REL_MAX) {
 				retval = -EINVAL;
@@ -346,7 +346,7 @@
 			}
 			set_bit(arg, udev->dev->relbit);
 			break;
-			
+
 		case UI_SET_ABSBIT:
 			if (arg > ABS_MAX) {
 				retval = -EINVAL;
@@ -354,7 +354,7 @@
 			}
 			set_bit(arg, udev->dev->absbit);
 			break;
-			
+
 		case UI_SET_MSCBIT:
 			if (arg > MSC_MAX) {
 				retval = -EINVAL;
@@ -362,7 +362,7 @@
 			}
 			set_bit(arg, udev->dev->mscbit);
 			break;
-			
+
 		case UI_SET_LEDBIT:
 			if (arg > LED_MAX) {
 				retval = -EINVAL;
@@ -370,7 +370,7 @@
 			}
 			set_bit(arg, udev->dev->ledbit);
 			break;
-			
+
 		case UI_SET_SNDBIT:
 			if (arg > SND_MAX) {
 				retval = -EINVAL;
@@ -378,7 +378,7 @@
 			}
 			set_bit(arg, udev->dev->sndbit);
 			break;
-			
+
 		case UI_SET_FFBIT:
 			if (arg > FF_MAX) {
 				retval = -EINVAL;
@@ -386,7 +386,7 @@
 			}
 			set_bit(arg, udev->dev->ffbit);
 			break;
-			
+
 		default:
 			retval = -EFAULT;
 	}
diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- a/drivers/input/mouse/logips2pp.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/mouse/logips2pp.c	Tue May  4 22:10:38 2004
@@ -63,7 +63,6 @@
 		packet[0] &= 0x0f;
 		packet[1] = 0;
 		packet[2] = 0;
-
 	}
 }
 
@@ -76,18 +75,9 @@
 
 static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
 {
-	unsigned char d;
-	int i;
-
-	if (psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11))
+	if (psmouse_sliced_command(psmouse, command))
 		return -1;
 
-	for (i = 6; i >= 0; i -= 2) {
-		d = (command >> i) & 3;
-		if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
-			return -1;
-	}
-
 	if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
 		return -1;
 
@@ -99,7 +89,7 @@
  * enabled if we do nothing to it. Of course I put this in because I want it
  * disabled :P
  * 1 - enabled (if previously disabled, also default)
- * 0/2 - disabled 
+ * 0/2 - disabled
  */
 
 static void ps2pp_set_smartscroll(struct psmouse *psmouse)
@@ -113,14 +103,11 @@
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
 
-	if (psmouse_smartscroll == 1) 
-		param[0] = 1;
-	else
-	if (psmouse_smartscroll > 2)
-		return;
-
-	/* else leave param[0] == 0 to disable */
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	if (psmouse_smartscroll < 2) {
+		/* 0 - disabled, 1 - enabled */
+		param[0] = psmouse_smartscroll;
+		psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	}
 }
 
 /*
@@ -138,111 +125,128 @@
 	psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
 }
 
+
+static int is_model_in_list(unsigned char model, int *model_list)
+{
+	int i;
+
+	for (i = 0; model_list[i] != -1; i++)
+		if (model == model_list[i])
+			return 1;
+	return 0;
+}
+
 /*
- * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or
- * touchpad.
+ * Set up input device's properties based on the detected mouse model.
  */
 
-static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
+static void ps2pp_set_properties(struct psmouse *psmouse, unsigned char protocol,
+				 unsigned char model, unsigned char buttons)
 {
-	int i;
 	static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
 	static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
-	static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
-						76, 80, 81, 83, 88, 96, 97, 112, -1 };
 	static int logitech_mx[] = { 61, 112, -1 };
 
 	psmouse->vendor = "Logitech";
-	psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+	psmouse->model = model;
 
-	if (param[1] < 3)
+	if (buttons < 3)
 		clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
-	if (param[1] < 2)
+	if (buttons < 2)
 		clear_bit(BTN_RIGHT, psmouse->dev.keybit);
 
-	psmouse->type = PSMOUSE_PS2;
+	if (protocol == PSMOUSE_PS2PP) {
 
-	for (i = 0; logitech_ps2pp[i] != -1; i++)
-		if (logitech_ps2pp[i] == psmouse->model)
-			psmouse->type = PSMOUSE_PS2PP;
-
-	if (psmouse->type == PSMOUSE_PS2PP) {
-
-		for (i = 0; logitech_4btn[i] != -1; i++)
-			if (logitech_4btn[i] == psmouse->model)
-				set_bit(BTN_SIDE, psmouse->dev.keybit);
-
-		for (i = 0; logitech_wheel[i] != -1; i++)
-			if (logitech_wheel[i] == psmouse->model) {
-				set_bit(REL_WHEEL, psmouse->dev.relbit);
-				psmouse->name = "Wheel Mouse";
-			}
+		if (is_model_in_list(model, logitech_4btn))
+			set_bit(BTN_SIDE, psmouse->dev.keybit);
+
+		if (is_model_in_list(model, logitech_wheel)) {
+			set_bit(REL_WHEEL, psmouse->dev.relbit);
+			psmouse->name = "Wheel Mouse";
+		}
+
+		if (is_model_in_list(model, logitech_mx)) {
+			set_bit(BTN_SIDE, psmouse->dev.keybit);
+			set_bit(BTN_EXTRA, psmouse->dev.keybit);
+			set_bit(BTN_BACK, psmouse->dev.keybit);
+			set_bit(BTN_FORWARD, psmouse->dev.keybit);
+			set_bit(BTN_TASK, psmouse->dev.keybit);
+			psmouse->name = "MX Mouse";
+		}
+	}
+
+	if (protocol == PSMOUSE_PS2TPP) {
+		set_bit(REL_WHEEL, psmouse->dev.relbit);
+		set_bit(REL_HWHEEL, psmouse->dev.relbit);
+		psmouse->name = "TouchPad 3";
+	}
+}
 
-		for (i = 0; logitech_mx[i] != -1; i++)
-			if (logitech_mx[i]  == psmouse->model) {
-				set_bit(BTN_SIDE, psmouse->dev.keybit);
-				set_bit(BTN_EXTRA, psmouse->dev.keybit);
-				set_bit(BTN_BACK, psmouse->dev.keybit);
-				set_bit(BTN_FORWARD, psmouse->dev.keybit);
-				set_bit(BTN_TASK, psmouse->dev.keybit);
-				psmouse->name = "MX Mouse";
-			}
 
 /*
- * Do Logitech PS2++ / PS2T++ magic init.
+ * Logitech magic init. Detect whether the mouse is a Logitech one
+ * and its exact model and try turning on extended protocol for ones
+ * that support it.
  */
 
-		if (psmouse->model == 97) { /* TouchPad 3 */
+int ps2pp_init(struct psmouse *psmouse, int set_properties)
+{
+	static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
+					76, 80, 81, 83, 88, 96, 97, 112, -1 };
+	unsigned char param[4];
+	unsigned char protocol = PSMOUSE_PS2;
+	unsigned char model, buttons;
 
-			set_bit(REL_WHEEL, psmouse->dev.relbit);
-			set_bit(REL_HWHEEL, psmouse->dev.relbit);
+	param[0] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	param[1] = 0;
+	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
 
-			param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
+	if (param[1] != 0) {
+		model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+		buttons = param[1];
+/*
+ * Do Logitech PS2++ / PS2T++ magic init.
+ */
+		if (model == 97) { /* Touch Pad 3 */
+
+			/* Unprotect RAM */
+			param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
 			psmouse_command(psmouse, param, 0x30d1);
-			param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
+			/* Enable features */
+			param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
 			psmouse_command(psmouse, param, 0x30d1);
-			param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
+			/* Enable PS2++ */
+			param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
 			psmouse_command(psmouse, param, 0x30d1);
 
 			param[0] = 0;
 			if (!psmouse_command(psmouse, param, 0x13d1) &&
-				param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
-				psmouse->name = "TouchPad 3";
-				return PSMOUSE_PS2TPP;
+			    param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+				protocol = PSMOUSE_PS2TPP;
 			}
 
-		} else {
+		} else if (is_model_in_list(model, logitech_ps2pp)) {
 
 			param[0] = param[1] = param[2] = 0;
 			ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
 			ps2pp_cmd(psmouse, param, 0xDB);
 
-			if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
-				(param[2] & 3) == ((param[1] >> 2) & 3)) {
-					ps2pp_set_smartscroll(psmouse);
-					return PSMOUSE_PS2PP;
+			if ((param[0] & 0x78) == 0x48 &&
+			    (param[1] & 0xf3) == 0xc2 &&
+			    (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
+				ps2pp_set_smartscroll(psmouse);
+				protocol = PSMOUSE_PS2PP;
 			}
 		}
-	}
-
-	return 0;
-}
-
-/*
- * Logitech magic init.
- */
-int ps2pp_detect(struct psmouse *psmouse)
-{
-	unsigned char param[4];
 
-	param[0] = 0;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
-	param[1] = 0;
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+		if (set_properties)
+			ps2pp_set_properties(psmouse, protocol, model, buttons);
+	}
 
-	return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0;
+	return protocol;
 }
 
diff -Nru a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
--- a/drivers/input/mouse/logips2pp.h	Tue May  4 22:10:38 2004
+++ b/drivers/input/mouse/logips2pp.h	Tue May  4 22:10:38 2004
@@ -10,8 +10,9 @@
 
 #ifndef _LOGIPS2PP_H
 #define _LOGIPS2PP_H
-struct psmouse;
+
 void ps2pp_process_packet(struct psmouse *psmouse);
 void ps2pp_set_800dpi(struct psmouse *psmouse);
-int ps2pp_detect(struct psmouse *psmouse);
+int ps2pp_init(struct psmouse *psmouse, int set_properties);
+
 #endif
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/mouse/psmouse-base.c	Tue May  4 22:10:38 2004
@@ -43,9 +43,9 @@
 module_param_named(smartscroll, psmouse_smartscroll, bool, 0);
 MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
 
-unsigned int psmouse_resetafter;
+static unsigned int psmouse_resetafter;
 module_param_named(resetafter, psmouse_resetafter, uint, 0);
-MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
 
 __obsolete_setup("psmouse_noext");
 __obsolete_setup("psmouse_resolution=");
@@ -56,15 +56,22 @@
 static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
 
 /*
- * psmouse_process_packet() analyzes the PS/2 mouse packet contents and
- * reports relevant events to the input module.
+ * psmouse_process_byte() analyzes the PS/2 data stream and reports
+ * relevant events to the input module once full packet has arrived.
  */
 
-static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
 	struct input_dev *dev = &psmouse->dev;
 	unsigned char *packet = psmouse->packet;
 
+	if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS))
+		return PSMOUSE_GOOD_DATA;
+
+/*
+ * Full packet accumulated, process it
+ */
+
 	input_regs(dev, regs);
 
 /*
@@ -112,6 +119,8 @@
 	input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
 
 	input_sync(dev);
+
+	return PSMOUSE_FULL_PACKET;
 }
 
 /*
@@ -123,6 +132,7 @@
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct psmouse *psmouse = serio->private;
+	psmouse_ret_t rc;
 
 	if (psmouse->state == PSMOUSE_IGNORE)
 		goto out;
@@ -180,7 +190,7 @@
 		if (psmouse->pktcnt == 2) {
 			if (psmouse->packet[1] == PSMOUSE_RET_ID) {
 				psmouse->state = PSMOUSE_IGNORE;
-				serio_rescan(serio);
+				serio_reconnect(serio);
 				goto out;
 			}
 			if (psmouse->type == PSMOUSE_SYNAPTICS) {
@@ -193,19 +203,32 @@
 		}
 	}
 
-	if (psmouse->type == PSMOUSE_SYNAPTICS) {
-		/*
-		 * The synaptics driver has its own resync logic,
-		 * so it needs to receive all bytes one at a time.
-		 */
-		synaptics_process_byte(psmouse, regs);
-		goto out;
-	}
+	rc = psmouse->protocol_handler(psmouse, regs);
 
-	if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
-		psmouse_process_packet(psmouse, regs);
-		psmouse->pktcnt = 0;
-		goto out;
+	switch (rc) {
+		case PSMOUSE_BAD_DATA:
+			printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
+				psmouse->name, psmouse->phys, psmouse->pktcnt);
+			psmouse->pktcnt = 0;
+
+			if (++psmouse->out_of_sync == psmouse_resetafter) {
+				psmouse->state = PSMOUSE_IGNORE;
+				printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
+				serio_reconnect(psmouse->serio);
+			}
+			break;
+
+		case PSMOUSE_FULL_PACKET:
+			psmouse->pktcnt = 0;
+			if (psmouse->out_of_sync) {
+				psmouse->out_of_sync = 0;
+				printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
+					psmouse->name, psmouse->phys);
+			}
+			break;
+
+		case PSMOUSE_GOOD_DATA:
+			break;
 	}
 out:
 	return IRQ_HANDLED;
@@ -289,6 +312,30 @@
 
 
 /*
+ * psmouse_sliced_command() sends an extended PS/2 command to the mouse
+ * using sliced syntax, understood by advanced devices, such as Logitech
+ * or Synaptics touchpads. The command is encoded as:
+ * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+ * is the command.
+ */
+int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
+{
+	int i;
+
+	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
+		return -1;
+
+	for (i = 6; i >= 0; i -= 2) {
+		unsigned char d = (command >> i) & 3;
+		if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
+			return -1;
+	}
+
+	return 0;
+}
+
+
+/*
  * psmouse_reset() resets the mouse into power-on state.
  */
 int psmouse_reset(struct psmouse *psmouse)
@@ -363,23 +410,23 @@
  * the mouse may have.
  */
 
-static int psmouse_extensions(struct psmouse *psmouse)
+static int psmouse_extensions(struct psmouse *psmouse,
+			      unsigned int max_proto, int set_properties)
 {
 	int synaptics_hardware = 0;
 
-	psmouse->vendor = "Generic";
-	psmouse->name = "Mouse";
-	psmouse->model = 0;
-
 /*
  * Try Synaptics TouchPad
  */
-	if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
+	if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
 		synaptics_hardware = 1;
-		psmouse->vendor = "Synaptics";
-		psmouse->name = "TouchPad";
 
-		if (psmouse_max_proto > PSMOUSE_IMEX) {
+		if (set_properties) {
+			psmouse->vendor = "Synaptics";
+			psmouse->name = "TouchPad";
+		}
+
+		if (max_proto > PSMOUSE_IMEX) {
 			if (synaptics_init(psmouse) == 0)
 				return PSMOUSE_SYNAPTICS;
 /*
@@ -387,7 +434,7 @@
  * Unfortunately Logitech/Genius probes confuse some firmware versions so
  * we'll have to skip them.
  */
-			psmouse_max_proto = PSMOUSE_IMEX;
+			max_proto = PSMOUSE_IMEX;
 		}
 /*
  * Make sure that touchpad is in relative mode, gestures (taps) are enabled
@@ -395,35 +442,45 @@
 		synaptics_reset(psmouse);
 	}
 
-	if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
-		set_bit(BTN_SIDE, psmouse->dev.keybit);
-		set_bit(REL_WHEEL, psmouse->dev.relbit);
+	if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
+
+		if (set_properties) {
+			set_bit(BTN_EXTRA, psmouse->dev.keybit);
+			set_bit(BTN_SIDE, psmouse->dev.keybit);
+			set_bit(REL_WHEEL, psmouse->dev.relbit);
+			psmouse->vendor = "Genius";
+			psmouse->name = "Wheel Mouse";
+		}
 
-		psmouse->vendor = "Genius";
-		psmouse->name = "Wheel Mouse";
 		return PSMOUSE_GENPS;
 	}
 
-	if (psmouse_max_proto > PSMOUSE_IMEX) {
-		int type = ps2pp_detect(psmouse);
-		if (type)
+	if (max_proto > PSMOUSE_IMEX) {
+		int type = ps2pp_init(psmouse, set_properties);
+		if (type > PSMOUSE_PS2)
 			return type;
 	}
 
-	if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
-		set_bit(REL_WHEEL, psmouse->dev.relbit);
+	if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
 
-		if (psmouse_max_proto >= PSMOUSE_IMEX &&
-					im_explorer_detect(psmouse)) {
-			set_bit(BTN_SIDE, psmouse->dev.keybit);
-			set_bit(BTN_EXTRA, psmouse->dev.keybit);
+		if (set_properties) {
+			set_bit(REL_WHEEL, psmouse->dev.relbit);
+			if (!psmouse->name)
+				psmouse->name = "Wheel Mouse";
+		}
+
+		if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {
+
+			if (!set_properties) {
+				set_bit(BTN_SIDE, psmouse->dev.keybit);
+				set_bit(BTN_EXTRA, psmouse->dev.keybit);
+				if (!psmouse->name)
+					psmouse->name = "Explorer Mouse";
+			}
 
-			psmouse->name = "Explorer Mouse";
 			return PSMOUSE_IMEX;
 		}
 
-		psmouse->name = "Wheel Mouse";
 		return PSMOUSE_IMPS;
 	}
 
@@ -473,12 +530,7 @@
 	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
 		printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);
 
-/*
- * And here we try to determine if it has any extensions over the
- * basic PS/2 3-button mouse.
- */
-
-	return psmouse->type = psmouse_extensions(psmouse);
+	return 0;
 }
 
 /*
@@ -616,7 +668,6 @@
 	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
 	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-
 	psmouse->state = PSMOUSE_CMD_MODE;
 	psmouse->serio = serio;
 	psmouse->dev.private = psmouse;
@@ -628,13 +679,21 @@
 		return;
 	}
 
-	if (psmouse_probe(psmouse) <= 0) {
+	if (psmouse_probe(psmouse) < 0) {
 		serio_close(serio);
 		kfree(psmouse);
 		serio->private = NULL;
 		return;
 	}
 
+	psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
+	if (!psmouse->vendor)
+		psmouse->vendor = "Generic";
+	if (!psmouse->name)
+		psmouse->name = "Mouse";
+	if (!psmouse->protocol_handler)
+		psmouse->protocol_handler = psmouse_process_byte;
+
 	sprintf(psmouse->devname, "%s %s %s",
 		psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
 	sprintf(psmouse->phys, "%s/input0",
@@ -668,27 +727,24 @@
 {
 	struct psmouse *psmouse = serio->private;
 	struct serio_dev *dev = serio->dev;
-	int old_type;
 
 	if (!dev || !psmouse) {
 		printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
 
-	old_type = psmouse->type;
-
 	psmouse->state = PSMOUSE_CMD_MODE;
-	psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0;
+	psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
 	if (psmouse->reconnect) {
 	       if (psmouse->reconnect(psmouse))
 			return -1;
-	} else if (psmouse_probe(psmouse) != old_type)
+	} else if (psmouse_probe(psmouse) < 0 ||
+		   psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
 		return -1;
 
 	/* ok, the device type (and capabilities) match the old one,
 	 * we can continue using it, complete intialization
 	 */
-	psmouse->type = old_type;
 	psmouse_initialize(psmouse);
 
 	if (psmouse->ptport) {
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	Tue May  4 22:10:38 2004
+++ b/drivers/input/mouse/psmouse.h	Tue May  4 22:10:38 2004
@@ -22,6 +22,13 @@
 #define PSMOUSE_ACTIVATED	1
 #define PSMOUSE_IGNORE		2
 
+/* psmouse protocol handler return codes */
+typedef enum {
+	PSMOUSE_BAD_DATA,
+	PSMOUSE_GOOD_DATA,
+	PSMOUSE_FULL_PACKET
+} psmouse_ret_t;
+
 struct psmouse;
 
 struct psmouse_ptport {
@@ -45,6 +52,7 @@
 	unsigned char type;
 	unsigned char model;
 	unsigned long last;
+	unsigned long out_of_sync;
 	unsigned char state;
 	char acking;
 	volatile char ack;
@@ -52,6 +60,7 @@
 	char devname[64];
 	char phys[32];
 
+	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); 
 	int (*reconnect)(struct psmouse *psmouse);
 	void (*disconnect)(struct psmouse *psmouse);
 };
@@ -65,10 +74,10 @@
 #define PSMOUSE_SYNAPTICS 	7
 
 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
+int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
 int psmouse_reset(struct psmouse *psmouse);
 
 extern int psmouse_smartscroll;
 extern unsigned int psmouse_rate;
-extern unsigned int psmouse_resetafter;
 
 #endif /* _PSMOUSE_H */
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/mouse/synaptics.c	Tue May  4 22:10:38 2004
@@ -44,33 +44,11 @@
  ****************************************************************************/
 
 /*
- * Use the Synaptics extended ps/2 syntax to write a special command byte.
- * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
- *                  is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
- *                  and synaptics_mode_cmd)
- */
-static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command)
-{
-	int i;
-
-	if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
-		return -1;
-
-	for (i = 6; i >= 0; i -= 2) {
-		unsigned char d = (command >> i) & 3;
-		if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
-			return -1;
-	}
-
-	return 0;
-}
-
-/*
  * Send a command to the synpatics touchpad by special commands
  */
 static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
 {
-	if (synaptics_special_cmd(psmouse, c))
+	if (psmouse_sliced_command(psmouse, c))
 		return -1;
 	if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
 		return -1;
@@ -84,7 +62,7 @@
 {
 	unsigned char param[1];
 
-	if (synaptics_special_cmd(psmouse, mode))
+	if (psmouse_sliced_command(psmouse, mode))
 		return -1;
 	param[0] = SYN_PS_SET_MODE2;
 	if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
@@ -118,17 +96,31 @@
 
 	if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
 		return -1;
-	priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+	priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
 	priv->ext_cap = 0;
 	if (!SYN_CAP_VALID(priv->capabilities))
 		return -1;
 
-	if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) {
+	/*
+	 * Unless capExtended is set the rest of the flags should be ignored
+	 */
+	if (!SYN_CAP_EXTENDED(priv->capabilities))
+		priv->capabilities = 0;
+
+	if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
 		if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
 			printk(KERN_ERR "Synaptics claims to have extended capabilities,"
 			       " but I'm not able to read them.");
-		} else
-			priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+		} else {
+			priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
+
+			/*
+			 * if nExtBtn is greater than 8 it should be considered
+			 * invalid and treated as 0
+			 */
+			if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
+				priv->ext_cap &= 0xff0fff;
+		}
 	}
 	return 0;
 }
@@ -167,11 +159,12 @@
 
 	if (SYN_CAP_EXTENDED(priv->capabilities)) {
 		printk(KERN_INFO " Touchpad has extended capability bits\n");
-		if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
-		    SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8)
+		if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
 			printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
 			       (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
-		else if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
+		if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+			printk(KERN_INFO " -> middle button\n");
+		if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
 			printk(KERN_INFO " -> four buttons\n");
 		if (SYN_CAP_MULTIFINGER(priv->capabilities))
 			printk(KERN_INFO " -> multifinger detection\n");
@@ -219,21 +212,12 @@
 /*****************************************************************************
  *	Synaptics pass-through PS/2 port support
  ****************************************************************************/
-static int synaptics_pt_open(struct serio *port)
-{
-	return 0;
-}
-
-static void synaptics_pt_close(struct serio *port)
-{
-}
-
 static int synaptics_pt_write(struct serio *port, unsigned char c)
 {
 	struct psmouse *parent = port->driver;
 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
-	if (synaptics_special_cmd(parent, c))
+	if (psmouse_sliced_command(parent, c))
 		return -1;
 	if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
 		return -1;
@@ -289,166 +273,12 @@
 	port->serio.name = "Synaptics pass-through";
 	port->serio.phys = "synaptics-pt/serio0";
 	port->serio.write = synaptics_pt_write;
-	port->serio.open = synaptics_pt_open;
-	port->serio.close = synaptics_pt_close;
 	port->serio.driver = psmouse;
 
 	port->activate = synaptics_pt_activate;
 }
 
 /*****************************************************************************
- *	Driver initialization/cleanup functions
- ****************************************************************************/
-
-static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
-{
-	dev->absmin[axis] = min;
-	dev->absmax[axis] = max;
-	dev->absfuzz[axis] = fuzz;
-	dev->absflat[axis] = flat;
-
-	set_bit(axis, dev->absbit);
-}
-
-static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
-{
-	set_bit(EV_ABS, dev->evbit);
-	set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
-	set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
-	set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
-	set_bit(ABS_TOOL_WIDTH, dev->absbit);
-
-	set_bit(EV_KEY, dev->evbit);
-	set_bit(BTN_TOUCH, dev->keybit);
-	set_bit(BTN_TOOL_FINGER, dev->keybit);
-	set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
-	set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
-
-	set_bit(BTN_LEFT, dev->keybit);
-	set_bit(BTN_RIGHT, dev->keybit);
-	set_bit(BTN_FORWARD, dev->keybit);
-	set_bit(BTN_BACK, dev->keybit);
-	if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
-		switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
-		default:
-			/*
-			 * if nExtBtn is greater than 8 it should be considered
-			 * invalid and treated as 0
-			 */
-			break;
-		case 8:
-			set_bit(BTN_7, dev->keybit);
-			set_bit(BTN_6, dev->keybit);
-		case 6:
-			set_bit(BTN_5, dev->keybit);
-			set_bit(BTN_4, dev->keybit);
-		case 4:
-			set_bit(BTN_3, dev->keybit);
-			set_bit(BTN_2, dev->keybit);
-		case 2:
-			set_bit(BTN_1, dev->keybit);
-			set_bit(BTN_0, dev->keybit);
-			break;
-		}
-	}
-
-	clear_bit(EV_REL, dev->evbit);
-	clear_bit(REL_X, dev->relbit);
-	clear_bit(REL_Y, dev->relbit);
-}
-
-void synaptics_reset(struct psmouse *psmouse)
-{
-	/* reset touchpad back to relative mode, gestures enabled */
-	synaptics_mode_cmd(psmouse, 0);
-}
-
-static void synaptics_disconnect(struct psmouse *psmouse)
-{
-	synaptics_reset(psmouse);
-	kfree(psmouse->private);
-}
-
-static int synaptics_reconnect(struct psmouse *psmouse)
-{
-	struct synaptics_data *priv = psmouse->private;
-	struct synaptics_data old_priv = *priv;
-
-	if (!synaptics_detect(psmouse))
-		return -1;
-
-	if (synaptics_query_hardware(psmouse)) {
-		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
-		return -1;
-	}
-
-	if (old_priv.identity != priv->identity ||
-	    old_priv.model_id != priv->model_id ||
-	    old_priv.capabilities != priv->capabilities ||
-    	    old_priv.ext_cap != priv->ext_cap)
-    		return -1;
-
-	if (synaptics_set_mode(psmouse, 0)) {
-		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-int synaptics_detect(struct psmouse *psmouse)
-{
-	unsigned char param[4];
-
-	param[0] = 0;
-
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
-	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
-
-	return param[1] == 0x47;
-}
-
-int synaptics_init(struct psmouse *psmouse)
-{
-	struct synaptics_data *priv;
-
-	psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
-	if (!priv)
-		return -1;
-	memset(priv, 0, sizeof(struct synaptics_data));
-
-	if (synaptics_query_hardware(psmouse)) {
-		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
-		goto init_fail;
-	}
-
-	if (synaptics_set_mode(psmouse, 0)) {
-		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
-		goto init_fail;
-	}
-
-	priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
-
-	if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
-       		synaptics_pt_create(psmouse);
-
-	print_ident(priv);
-	set_input_params(&psmouse->dev, priv);
-
-	psmouse->disconnect = synaptics_disconnect;
-	psmouse->reconnect = synaptics_reconnect;
-
-	return 0;
-
- init_fail:
-	kfree(priv);
-	return -1;
-}
-
-/*****************************************************************************
  *	Functions to interpret the absolute mode packets
  ****************************************************************************/
 
@@ -471,17 +301,17 @@
 
 		hw->left  = (buf[0] & 0x01) ? 1 : 0;
 		hw->right = (buf[0] & 0x02) ? 1 : 0;
-		if (SYN_CAP_EXTENDED(priv->capabilities) &&
-		    (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
-			hw->up = ((buf[3] & 0x01)) ? 1 : 0;
-			if (hw->left)
-				hw->up = !hw->up;
-			hw->down = ((buf[3] & 0x02)) ? 1 : 0;
-			if (hw->right)
-				hw->down = !hw->down;
+
+		if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+			hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+
+		if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+			hw->up   = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+			hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
 		}
+
 		if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
-		    ((buf[3] & 2) ? !hw->right : hw->right)) {
+		    ((buf[0] ^ buf[3]) & 0x02)) {
 			switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
 			default:
 				/*
@@ -490,17 +320,17 @@
 				 */
 				break;
 			case 8:
-				hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
-				hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
+				hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
+				hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
 			case 6:
-				hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
-				hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
+				hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
+				hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
 			case 4:
-				hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
-				hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
+				hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
+				hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
 			case 2:
-				hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
-				hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
+				hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
+				hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
 			}
 		}
 	} else {
@@ -525,6 +355,7 @@
 	struct synaptics_hw_state hw;
 	int num_fingers;
 	int finger_width;
+	int i;
 
 	synaptics_parse_hw_state(psmouse->packet, priv, &hw);
 
@@ -570,32 +401,20 @@
 	input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
 	input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
 
-	input_report_key(dev, BTN_LEFT,    hw.left);
-	input_report_key(dev, BTN_RIGHT,   hw.right);
-	input_report_key(dev, BTN_FORWARD, hw.up);
-	input_report_key(dev, BTN_BACK,    hw.down);
-	if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
-		switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
-		default:
-			/*
-			 * if nExtBtn is greater than 8 it should be considered
-			 * invalid and treated as 0
-			 */
-			break;
-		case 8:
-			input_report_key(dev, BTN_7,       hw.b7);
-			input_report_key(dev, BTN_6,       hw.b6);
-		case 6:
-			input_report_key(dev, BTN_5,       hw.b5);
-			input_report_key(dev, BTN_4,       hw.b4);
-		case 4:
-			input_report_key(dev, BTN_3,       hw.b3);
-			input_report_key(dev, BTN_2,       hw.b2);
-		case 2:
-			input_report_key(dev, BTN_1,       hw.b1);
-			input_report_key(dev, BTN_0,       hw.b0);
-			break;
-		}
+	input_report_key(dev, BTN_LEFT, hw.left);
+	input_report_key(dev, BTN_RIGHT, hw.right);
+
+	if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+		input_report_key(dev, BTN_MIDDLE, hw.middle);
+
+	if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+		input_report_key(dev, BTN_FORWARD, hw.up);
+		input_report_key(dev, BTN_BACK, hw.down);
+	}
+
+	for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
+		input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i));
+
 	input_sync(dev);
 }
 
@@ -607,6 +426,9 @@
 	static unsigned char oldabs_mask[]	= { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
 	static unsigned char oldabs_rslt[]	= { 0xC0, 0x00, 0x00, 0x80, 0x00 };
 
+	if (idx < 0 || idx > 4)
+		return 0;
+
 	switch (pkt_type) {
 		case SYN_NEWABS:
 		case SYN_NEWABS_RELAXED:
@@ -637,7 +459,7 @@
 	return SYN_NEWABS_STRICT;
 }
 
-void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
 	struct input_dev *dev = &psmouse->dev;
 	struct synaptics_data *priv = psmouse->private;
@@ -645,11 +467,6 @@
 	input_regs(dev, regs);
 
 	if (psmouse->pktcnt >= 6) { /* Full packet received */
-		if (priv->out_of_sync) {
-			priv->out_of_sync = 0;
-			printk(KERN_NOTICE "Synaptics driver resynced.\n");
-		}
-
 		if (unlikely(priv->pkt_type == SYN_NEWABS))
 			priv->pkt_type = synaptics_detect_pkt_type(psmouse);
 
@@ -657,16 +474,142 @@
 			synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
 		else
 			synaptics_process_packet(psmouse);
-		psmouse->pktcnt = 0;
 
-	} else if (psmouse->pktcnt &&
-		   !synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type)) {
-		printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
-		psmouse->pktcnt = 0;
-		if (++priv->out_of_sync == psmouse_resetafter) {
-			psmouse->state = PSMOUSE_IGNORE;
-			printk(KERN_NOTICE "synaptics: issuing reconnect request\n");
-			serio_reconnect(psmouse->serio);
-		}
+		return PSMOUSE_FULL_PACKET;
+	}
+
+	return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ?
+		PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
+}
+
+/*****************************************************************************
+ *	Driver initialization/cleanup functions
+ ****************************************************************************/
+static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
+{
+	int i;
+
+	set_bit(EV_ABS, dev->evbit);
+	input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
+	input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+	set_bit(ABS_TOOL_WIDTH, dev->absbit);
+
+	set_bit(EV_KEY, dev->evbit);
+	set_bit(BTN_TOUCH, dev->keybit);
+	set_bit(BTN_TOOL_FINGER, dev->keybit);
+	set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
+	set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+
+	set_bit(BTN_LEFT, dev->keybit);
+	set_bit(BTN_RIGHT, dev->keybit);
+
+	if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+		set_bit(BTN_MIDDLE, dev->keybit);
+
+	if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+		set_bit(BTN_FORWARD, dev->keybit);
+		set_bit(BTN_BACK, dev->keybit);
+	}
+
+	for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
+		set_bit(BTN_0 + i, dev->keybit);
+
+	clear_bit(EV_REL, dev->evbit);
+	clear_bit(REL_X, dev->relbit);
+	clear_bit(REL_Y, dev->relbit);
+}
+
+void synaptics_reset(struct psmouse *psmouse)
+{
+	/* reset touchpad back to relative mode, gestures enabled */
+	synaptics_mode_cmd(psmouse, 0);
+}
+
+static void synaptics_disconnect(struct psmouse *psmouse)
+{
+	synaptics_reset(psmouse);
+	kfree(psmouse->private);
+}
+
+static int synaptics_reconnect(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv = psmouse->private;
+	struct synaptics_data old_priv = *priv;
+
+	if (!synaptics_detect(psmouse))
+		return -1;
+
+	if (synaptics_query_hardware(psmouse)) {
+		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+		return -1;
+	}
+
+	if (old_priv.identity != priv->identity ||
+	    old_priv.model_id != priv->model_id ||
+	    old_priv.capabilities != priv->capabilities ||
+	    old_priv.ext_cap != priv->ext_cap)
+		return -1;
+
+	if (synaptics_set_mode(psmouse, 0)) {
+		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int synaptics_detect(struct psmouse *psmouse)
+{
+	unsigned char param[4];
+
+	param[0] = 0;
+
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+	psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+	return param[1] == 0x47;
+}
+
+int synaptics_init(struct psmouse *psmouse)
+{
+	struct synaptics_data *priv;
+
+	psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
+	if (!priv)
+		return -1;
+	memset(priv, 0, sizeof(struct synaptics_data));
+
+	if (synaptics_query_hardware(psmouse)) {
+		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+		goto init_fail;
+	}
+
+	if (synaptics_set_mode(psmouse, 0)) {
+		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+		goto init_fail;
 	}
+
+	priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
+
+	if (SYN_CAP_PASS_THROUGH(priv->capabilities))
+		synaptics_pt_create(psmouse);
+
+	print_ident(priv);
+	set_input_params(&psmouse->dev, priv);
+
+	psmouse->protocol_handler = synaptics_process_byte;
+	psmouse->disconnect = synaptics_disconnect;
+	psmouse->reconnect = synaptics_reconnect;
+
+	return 0;
+
+ init_fail:
+	kfree(priv);
+	return -1;
 }
+
+
diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
--- a/drivers/input/mouse/synaptics.h	Tue May  4 22:10:38 2004
+++ b/drivers/input/mouse/synaptics.h	Tue May  4 22:10:38 2004
@@ -9,7 +9,6 @@
 #ifndef _SYNAPTICS_H
 #define _SYNAPTICS_H
 
-extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
 extern int synaptics_detect(struct psmouse *psmouse);
 extern int synaptics_init(struct psmouse *psmouse);
 extern void synaptics_reset(struct psmouse *psmouse);
@@ -44,13 +43,14 @@
 
 /* synaptics capability bits */
 #define SYN_CAP_EXTENDED(c)		((c) & (1 << 23))
+#define SYN_CAP_MIDDLE_BUTTON(c)	((c) & (1 << 18))
 #define SYN_CAP_PASS_THROUGH(c)		((c) & (1 << 7))
 #define SYN_CAP_SLEEP(c)		((c) & (1 << 4))
 #define SYN_CAP_FOUR_BUTTON(c)		((c) & (1 << 3))
 #define SYN_CAP_MULTIFINGER(c)		((c) & (1 << 1))
 #define SYN_CAP_PALMDETECT(c)		((c) & (1 << 0))
 #define SYN_CAP_VALID(c)		((((c) & 0x00ff00) >> 8) == 0x47)
-#define SYN_EXT_CAP_REQUESTS(c)		((((c) & 0x700000) >> 20) == 1)
+#define SYN_EXT_CAP_REQUESTS(c)		(((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)	(((ec) & 0x00f000) >> 12)
 
 /* synaptics modes query bits */
@@ -86,18 +86,12 @@
 	int y;
 	int z;
 	int w;
-	int left;
-	int right;
-	int up;
-	int down;
-	int b0;
-	int b1;
-	int b2;
-	int b3;
-	int b4;
-	int b5;
-	int b6;
-	int b7;
+	unsigned int left:1;
+	unsigned int right:1;
+	unsigned int middle:1;
+	unsigned int up:1;
+	unsigned int down:1;
+	unsigned char ext_buttons;
 };
 
 struct synaptics_data {
@@ -108,7 +102,6 @@
 	unsigned long int identity;		/* Identification */
 
 	/* Data for normal processing */
-	unsigned int out_of_sync;		/* # of packets out of sync */
 	int old_w;				/* Previous w value */
 	unsigned char pkt_type;			/* packet type - old, new, etc */
 };
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/mousedev.c	Tue May  4 22:10:38 2004
@@ -391,9 +391,9 @@
 				list->impsseq = 0;
 				list->imexseq = 0;
 				list->mode = 0;
-				list->ps2[0] = 0xaa;
-				list->ps2[1] = 0x00;
-				list->bufsiz = 2;
+				list->ps2[1] = 0xaa;
+				list->ps2[2] = 0x00;
+				list->bufsiz = 3;
 				break;
 		}
 
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/serio/i8042.c	Tue May  4 22:10:38 2004
@@ -474,8 +474,17 @@
 	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
 		return -1;
 	param = 0xa4;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
+	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);
 		return -1;
+	}
 
 	if (mux_version)
 		*mux_version = ~param;
@@ -532,8 +541,8 @@
 		return -1;
 	
 	/* Workaround for broken chips which seem to support MUX, but in reality don't. */
-	/* They all report version 12.10 */
-	if (mux_version == 0xCA)
+	/* They all report version 10.12 */
+	if (mux_version == 0xAC)
 		return -1;
 
 	printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- a/drivers/input/serio/parkbd.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/serio/parkbd.c	Tue May  4 22:10:38 2004
@@ -86,20 +86,9 @@
 	return 0;
 }
 
-static int parkbd_open(struct serio *port)
-{
-	return 0;
-}
-
-static void parkbd_close(struct serio *port)
-{
-}
-
 static struct serio parkbd_port =
 {
 	.write	= parkbd_write,
-	.open	= parkbd_open,
-	.close	= parkbd_close,
 	.name	= parkbd_name,
 	.phys	= parkbd_phys,
 };
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/serio/q40kbd.c	Tue May  4 22:10:38 2004
@@ -47,23 +47,12 @@
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-
-static int q40kbd_open(struct serio *port)
-{
-	return 0;
-}
-static void q40kbd_close(struct serio *port)
-{
-}
-
 static struct serio q40kbd_port =
 {
 	.type	= SERIO_8042,
 	.name	= "Q40 kbd port",
 	.phys	= "Q40",
 	.write	= NULL,
-	.open	= q40kbd_open,
-	.close	= q40kbd_close,
 };
 
 static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/serio/serio.c	Tue May  4 22:10:38 2004
@@ -11,18 +11,18 @@
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or 
+ * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * 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 <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -108,7 +108,7 @@
 	struct serio_event *event;
 
 	list_for_each_safe(node, next, &serio_event_list) {
-		event = container_of(node, struct serio_event, node);	
+		event = container_of(node, struct serio_event, node);
 
 		down(&serio_sem);
 		if (event->serio == NULL)
@@ -152,7 +152,7 @@
 
 	do {
 		serio_handle_events();
-		wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); 
+		wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
 		if (current->flags & PF_FREEZE)
 			refrigerator(PF_FREEZE);
 	} while (!signal_pending(current));
@@ -293,7 +293,7 @@
 int serio_open(struct serio *serio, struct serio_dev *dev)
 {
 	serio->dev = dev;
-	if (serio->open(serio)) {
+	if (serio->open && serio->open(serio)) {
 		serio->dev = NULL;
 		return -1;
 	}
@@ -303,7 +303,8 @@
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
-	serio->close(serio);
+	if (serio->close)
+		serio->close(serio);
 	serio->dev = NULL;
 }
 
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/serio/serport.c	Tue May  4 22:10:38 2004
@@ -48,11 +48,6 @@
 	return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
 }
 
-static int serport_serio_open(struct serio *serio)
-{
-        return 0;
-}
-
 static void serport_serio_close(struct serio *serio)
 {
 	struct serport *serport = serio->driver;
@@ -87,7 +82,6 @@
 
 	serport->serio.type = SERIO_RS232;
 	serport->serio.write = serport_serio_write;
-	serport->serio.open = serport_serio_open;
 	serport->serio.close = serport_serio_close;
 	serport->serio.driver = serport;
 
@@ -135,7 +129,7 @@
 }
 
 /*
- * serport_ldisc_read() just waits indefinitely if everything goes well. 
+ * serport_ldisc_read() just waits indefinitely if everything goes well.
  * However, when the serio driver closes the serio port, it finishes,
  * returning 0 characters.
  */
@@ -165,7 +159,7 @@
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
-	
+
 	if (cmd == SPIOCSTYPE)
 		return get_user(serport->serio.type, (unsigned long *) arg);
 
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/touchscreen/gunze.c	Tue May  4 22:10:38 2004
@@ -124,12 +124,10 @@
 	memset(gunze, 0, sizeof(struct gunze));
 
 	init_input_dev(&gunze->dev);
-	gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);	
-	gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+	gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 	gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-	gunze->dev.absmin[ABS_X] = 96;   gunze->dev.absmin[ABS_Y] = 72;
-	gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000;
+	input_set_abs_params(&gunze->dev, ABS_X, 96, 4000, 0, 0);
+	input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0);
 
 	gunze->serio = serio;
 	serio->private = gunze;
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	Tue May  4 22:10:38 2004
+++ b/drivers/input/touchscreen/h3600_ts_input.c	Tue May  4 22:10:38 2004
@@ -1,11 +1,11 @@
 /*
  * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
  *
- *  Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com 
+ *  Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
  *
- *  Sponsored by Transvirtual Technology. 
- * 
- *  Derived from the code in h3600_ts.[ch] by Charles Flynn  
+ *  Sponsored by Transvirtual Technology.
+ *
+ *  Derived from the code in h3600_ts.[ch] by Charles Flynn
  */
 
 /*
@@ -75,7 +75,7 @@
 #define MAX_ID                  14
 
 #define H3600_MAX_LENGTH 16
-#define H3600_KEY 0xf 
+#define H3600_KEY 0xf
 
 #define H3600_SCANCODE_RECORD	1	 /* 1 -> record button */
 #define H3600_SCANCODE_CALENDAR 2	 /* 2 -> calendar */
@@ -118,13 +118,13 @@
         int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
 
-	/* 
-	 * This interrupt is only called when we release the key. So we have 
+	/*
+	 * This interrupt is only called when we release the key. So we have
 	 * to fake a key press.
-	 */ 	
+	 */
 	input_regs(dev, regs);
 	input_report_key(dev, KEY_SUSPEND, 1);
-	input_report_key(dev, KEY_SUSPEND, down); 	
+	input_report_key(dev, KEY_SUSPEND, down);
 	input_sync(dev);
 }
 
@@ -144,18 +144,18 @@
 	unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness);
 	struct h3600_dev *ts = dev->private;
 
-	/* Must be in this order */	
+	/* Must be in this order */
        	ts->serio->write(ts->serio, 1);
 	ts->serio->write(ts->serio, pwr);
-      	ts->serio->write(ts->serio, brightness); 
+      	ts->serio->write(ts->serio, brightness);
 	return 0;
 }
 
 static int suspended = 0;
-static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, 
+static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
 				void *data)
 {
-	struct input_dev *dev = (struct input_dev *) data;	
+	struct input_dev *dev = (struct input_dev *) data;
 
         switch (req) {
         case PM_SUSPEND: /* enter D1-D3 */
@@ -183,7 +183,7 @@
 /*
  * This function translates the native event packets to linux input event
  * packets. Some packets coming from serial are not touchscreen related. In
- * this case we send them off to be processed elsewhere. 
+ * this case we send them off to be processed elsewhere.
  */
 static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 {
@@ -206,7 +206,7 @@
                 Note: This is true for non interrupt generated key events.
                 */
                 case KEYBD_ID:
-			down = (ts->buf[0] & 0x80) ? 0 : 1; 
+			down = (ts->buf[0] & 0x80) ? 0 : 1;
 
 			switch (ts->buf[0] & 0x7f) {
 				case H3600_SCANCODE_RECORD:
@@ -218,7 +218,7 @@
 				case H3600_SCANCODE_CONTACTS:
 					key = KEY_PROG2;
                                         break;
-				case H3600_SCANCODE_Q:        
+				case H3600_SCANCODE_Q:
 					key = KEY_Q;
                                         break;
 				case H3600_SCANCODE_START:
@@ -237,9 +237,9 @@
 					key = KEY_DOWN;
                                         break;
 				default:
-					key = 0;	
-			}	
-                        if (key) 
+					key = 0;
+			}
+                        if (key)
                         	input_report_key(dev, key, down);
                         break;
                 /*
@@ -251,13 +251,13 @@
                  *       byte 0    1       2       3
                  */
                 case TOUCHS_ID:
-			if (!touched) { 
+			if (!touched) {
 				input_report_key(dev, BTN_TOUCH, 1);
 				touched = 1;
-			}			
+			}
 
 			if (ts->len) {
-				unsigned short x, y;				
+				unsigned short x, y;
 
 				x = ts->buf[0]; x <<= 8; x += ts->buf[1];
                                 y = ts->buf[2]; y <<= 8; y += ts->buf[3];
@@ -267,7 +267,7 @@
 			} else {
 		               	input_report_key(dev, BTN_TOUCH, 0);
 				touched = 0;
-			}	
+			}
                         break;
 		default:
 			/* Send a non input event elsewhere */
@@ -280,7 +280,7 @@
 /*
  * h3600ts_event() handles events from the input module.
  */
-static int h3600ts_event(struct input_dev *dev, unsigned int type, 
+static int h3600ts_event(struct input_dev *dev, unsigned int type,
 		 	 unsigned int code, int value)
 {
 	struct h3600_dev *ts = dev->private;
@@ -290,7 +290,7 @@
 		//	ts->serio->write(ts->serio, SOME_CMD);
 			return 0;
 		}
-	}					
+	}
 	return -1;
 }
 
@@ -323,12 +323,12 @@
         struct h3600_dev *ts = serio->private;
 
 	/*
-         * We have a new frame coming in. 
+         * We have a new frame coming in.
          */
 	switch (state) {
 		case STATE_SOF:
         		if (data == CHAR_SOF)
-                		state = STATE_ID;	
+                		state = STATE_ID;
 			return;
         	case STATE_ID:
 			ts->event = (data & 0xf0) >> 4;
@@ -344,7 +344,7 @@
 		case STATE_DATA:
 			ts->chksum += data;
 			ts->buf[ts->idx]= data;
-			if(++ts->idx == ts->len) 
+			if(++ts->idx == ts->len)
                         	state = STATE_EOF;
 			break;
 		case STATE_EOF:
@@ -382,7 +382,7 @@
         set_GPIO_IRQ_edge( GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE );
 
         if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
-			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,	
+			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
 			"h3600_action", &ts->dev)) {
 		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
 		kfree(ts);
@@ -390,24 +390,19 @@
 	}
 
         if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
-			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, 
+			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
 			"h3600_suspend", &ts->dev)) {
 		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
 		printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
 		kfree(ts);
 		return;
 	}
+
 	/* Now we have things going we setup our input device */
 	ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
-	ts->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-	ts->dev.ledbit[0] = BIT(LED_SLEEP); 
-
-	ts->dev.absmin[ABS_X] = 60;   ts->dev.absmin[ABS_Y] = 35;
-	ts->dev.absmax[ABS_X] = 985; ts->dev.absmax[ABS_Y] = 1024;
-	ts->dev.absfuzz[ABS_X] = 0; ts->dev.absfuzz[ABS_Y] = 0;
-
-	ts->serio = serio;
-	serio->private = ts;
+	ts->dev.ledbit[0] = BIT(LED_SLEEP);
+	input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
+	input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
 
 	set_bit(KEY_RECORD, ts->dev.keybit);
 	set_bit(KEY_Q, ts->dev.keybit);
@@ -422,6 +417,9 @@
 	ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
 	ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
 
+	ts->serio = serio;
+	serio->private = ts;
+
 	sprintf(ts->phys, "%s/input0", serio->phys);
 
        	ts->dev.event = h3600ts_event;
@@ -442,7 +440,7 @@
 
 	//h3600_flite_control(1, 25);     /* default brightness */
 #ifdef CONFIG_PM
-	ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, 
+	ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
 					h3600ts_pm_callback);
 	printk("registered pm callback\n");
 #endif
@@ -458,7 +456,7 @@
 static void h3600ts_disconnect(struct serio *serio)
 {
 	struct h3600_dev *ts = serio->private;
-	
+
         free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
         free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
 	input_unregister_device(&ts->dev);
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	Tue May  4 22:10:38 2004
+++ b/include/linux/input.h	Tue May  4 22:10:38 2004
@@ -655,7 +655,7 @@
 	struct ff_envelope envelope;
 
 /* Only used if waveform == FF_CUSTOM */
-	__u32 custom_len;	/* Number of samples  */	
+	__u32 custom_len;	/* Number of samples */
 	__s16 *custom_data;	/* Buffer of samples */
 /* Note: the data pointed by custom_data is copied by the driver. You can
  * therefore dispose of the memory after the upload/update */
@@ -749,8 +749,6 @@
 #define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
 	((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
 
-#define init_input_dev(dev)	do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
-
 #define SET_INPUT_KEYCODE(dev, scancode, val)			\
 		({	unsigned __old;				\
 		switch (dev->keycodesize) {			\
@@ -915,6 +913,12 @@
 #define to_handle(n) container_of(n,struct input_handle,d_node)
 #define to_handle_h(n) container_of(n,struct input_handle,h_node)
 
+static inline void init_input_dev(struct input_dev *dev)
+{
+	INIT_LIST_HEAD(&dev->h_list);
+	INIT_LIST_HEAD(&dev->node);
+}
+
 void input_register_device(struct input_dev *);
 void input_unregister_device(struct input_dev *);
 
@@ -932,14 +936,51 @@
 
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 
-#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
-#define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
-#define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
-#define input_report_ff(a,b,c)	input_event(a, EV_FF, b, c)
-#define input_report_ff_status(a,b,c)	input_event(a, EV_FF_STATUS, b, c)
+static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_KEY, code, !!value);
+}
+
+static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_REL, code, value);
+}
+
+static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_ABS, code, value);
+}
+
+static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_FF, code, value);
+}
+
+static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
+{
+	input_event(dev, EV_FF_STATUS, code, value);
+}
+
+static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
+{
+	dev->regs = regs;
+}
+
+static inline void input_sync(struct input_dev *dev)
+{
+	input_event(dev, EV_SYN, SYN_REPORT, 0);
+	dev->regs = NULL;
+}
+
+static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
+{
+	dev->absmin[axis] = min;
+	dev->absmax[axis] = max;
+	dev->absfuzz[axis] = fuzz;
+	dev->absflat[axis] = flat;
 
-#define input_regs(a,b)		do { (a)->regs = (b); } while (0)
-#define input_sync(a)		do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0)
+	dev->absbit[LONG(axis)] |= BIT(axis);
+}
 
 extern struct class_simple *input_class;