diff -urN synaptics-0.14.6.orig/eventcomm.c synaptics-0.14.6/eventcomm.c
--- synaptics-0.14.6.orig/eventcomm.c	2006-07-15 17:54:29.000000000 +0200
+++ synaptics-0.14.6/eventcomm.c	2008-01-06 23:44:09.000000000 +0100
@@ -40,16 +40,24 @@
  *	Function Definitions
  ****************************************************************************/
 
-static void
+static Bool
+grab_event_device(int fd)
+{
+    int ret;
+    SYSCALL(ret = ioctl(fd, EVIOCGRAB, (pointer)1));
+    return !(ret < 0);
+}
+
+static Bool
 EventDeviceOnHook(LocalDevicePtr local)
 {
     /* Try to grab the event device so that data don't leak to /dev/input/mice */
-    int ret;
-    SYSCALL(ret = ioctl(local->fd, EVIOCGRAB, (pointer)1));
-    if (ret < 0) {
+    if(!grab_event_device(local->fd)) {
 	xf86Msg(X_WARNING, "%s can't grab event device, errno=%d\n",
 		local->name, errno);
+	return FALSE;
     }
+    return TRUE;
 }
 
 static void
@@ -247,6 +255,7 @@
 	char fname[64];
 	int fd = -1;
 	Bool is_touchpad;
+	Bool is_grabbable;
 
 	sprintf(fname, "%s/%s%d", DEV_INPUT_EVENT, EVENT_DEV_NAME, i);
 	SYSCALL(fd = open(fname, O_RDONLY));
@@ -263,8 +272,16 @@
 	noent_cnt = 0;
 	have_evdev = TRUE;
 	is_touchpad = event_query_is_touchpad(fd);
+	/** 
+	 * Check whether device can be grabbed. This means there is a race 
+	 * condition with EventDeviceOnHook, which can't be solved cleanly
+	 * the way things are done with the current design. One possible 
+	 * solution would be to keep the file descriptor open.
+	 */
+	is_grabbable = grab_event_device(fd);
+
 	SYSCALL(close(fd));
-	if (is_touchpad) {
+	if (is_touchpad && is_grabbable) {
 	    xf86Msg(X_PROBED, "%s auto-dev sets device to %s\n",
 		    local->name, fname);
 	    xf86ReplaceStrOption(local->options, "Device", fname);
diff -urN synaptics-0.14.6.orig/synaptics.c synaptics-0.14.6/synaptics.c
--- synaptics-0.14.6.orig/synaptics.c	2006-07-15 17:54:29.000000000 +0200
+++ synaptics-0.14.6/synaptics.c	2008-01-06 23:03:26.000000000 +0100
@@ -543,7 +543,8 @@
 	return !Success;
     }
 
-    priv->proto_ops->DeviceOnHook(local);
+    if(!priv->proto_ops->DeviceOnHook(local))
+        return !Success;
 
     priv->comm.buffer = XisbNew(local->fd, 64);
     if (!priv->comm.buffer) {
diff -urN synaptics-0.14.6.orig/synproto.h synaptics-0.14.6/synproto.h
--- synaptics-0.14.6.orig/synproto.h	2006-07-09 18:53:02.000000000 +0200
+++ synaptics-0.14.6/synproto.h	2008-01-06 22:31:19.000000000 +0100
@@ -76,7 +76,7 @@
 struct CommData;
 
 struct SynapticsProtocolOperations {
-    void (*DeviceOnHook)(LocalDevicePtr local);
+    Bool (*DeviceOnHook)(LocalDevicePtr local);
     void (*DeviceOffHook)(LocalDevicePtr local);
     Bool (*QueryHardware)(LocalDevicePtr local, struct SynapticsHwInfo *synhw);
     Bool (*ReadHwState)(LocalDevicePtr local, struct SynapticsHwInfo *synhw,