diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/doc/doc.gpm gpm-1.19.5/doc/doc.gpm
--- gpm-1.19.5.orig/doc/doc.gpm	Thu Oct  4 23:38:13 2001
+++ gpm-1.19.5/doc/doc.gpm	Thu Oct  4 23:38:08 2001
@@ -421,6 +421,8 @@
 
 @item -s @var{number}
         Set the sample rate for the mouse device.
+        This currently only does anything for the ps2, imps2, and logi
+        protocols.
 
 @item -S @var{commands}
         Enable special-command processing, and optionally specify custom
diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/src/headers/defines.h gpm-1.19.5/src/headers/defines.h
--- gpm-1.19.5.orig/src/headers/defines.h	Wed Sep 19 08:56:43 2001
+++ gpm-1.19.5/src/headers/defines.h	Thu Oct  4 23:38:08 2001
@@ -54,6 +54,7 @@
 #define GPM_AUX_SET_SAMPLE     0xF3  /* Set sample rate */ 
 #define GPM_AUX_ENABLE_DEV     0xF4  /* Enable aux device */
 #define GPM_AUX_DISABLE_DEV    0xF5  /* Disable aux device */
+#define GPM_AUX_DEFAULTS       0xF6  /* Reset to defaults */
 #define GPM_AUX_RESET          0xFF  /* Reset aux device */
 #define GPM_AUX_ACK            0xFA  /* Command byte ACK. */ 
 
diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/src/headers/gpmInt.h gpm-1.19.5/src/headers/gpmInt.h
--- gpm-1.19.5.orig/src/headers/gpmInt.h	Thu Oct  4 23:38:13 2001
+++ gpm-1.19.5/src/headers/gpmInt.h	Thu Oct  4 23:38:08 2001
@@ -78,6 +78,7 @@
 #define GPM_AUX_SET_SAMPLE     0xF3  /* Set sample rate */ 
 #define GPM_AUX_ENABLE_DEV     0xF4  /* Enable aux device */
 #define GPM_AUX_DISABLE_DEV    0xF5  /* Disable aux device */
+#define GPM_AUX_DEFAULTS       0xF6  /* Reset to defaults */
 #define GPM_AUX_RESET          0xFF  /* Reset aux device */
 #define GPM_AUX_ACK            0xFA  /* Command byte ACK. */ 
 
diff -ruN -x Makefile -x configure -x config.cache -x config.h -x *.[178] -x gpm.info -x gpmdoc.ps -x gpmdoc.txt -x gpm-root.c -x stamp-h -x *.elc gpm-1.19.5.orig/src/mice.c gpm-1.19.5/src/mice.c
--- gpm-1.19.5.orig/src/mice.c	Thu Oct  4 23:38:13 2001
+++ gpm-1.19.5/src/mice.c	Thu Oct  4 23:38:08 2001
@@ -1719,82 +1719,112 @@
  * 
  * Returns 0 if OK, or >0 if 1 or more errors occurred.
  */
-static int write_to_mouse(int fd, unsigned char *data, size_t len)
+static int write_ps2(int fd, unsigned char cmd0, unsigned char cmd1,
+	size_t num, unsigned long int sleep)
 {
-  int i;
-  int error = 0;
-  for (i = 0; i < len; i++) {
-    unsigned char c;
-    write(fd, &data[i], 1);
-    read(fd, &c, 1);
-    if (c != GPM_AUX_ACK) {
+  int i, error = 0, rcnt;
+  unsigned char cmd[2], ret[512];
+
+  cmd[0] = cmd0; cmd[1] = cmd0;
+
+  write(fd, cmd, num);
+  if (sleep == -1)
+    usleep(50000);
+  else
+    usleep(sleep);
+
+  rcnt = read(fd, ret, sizeof(ret));
+  if (rcnt != num)
+    error++;
+
+  for (i = 0; i < rcnt; i++) {
+    if (ret[i] != GPM_AUX_ACK)
       error++;
-    }
   }
-
-  /* flush any left-over input */
-  usleep (30000);
-  tcflush (fd, TCIFLUSH);
   return(error);
 }
 
-
 /* intellimouse, ps2 version: Ben Pfaff and Colin Plumb */
 /* Autodetect: Steve Bennett */
-static Gpm_Type *I_imps2(int fd, unsigned short flags, struct Gpm_Type *type)
+static Gpm_Type *I_ps2(int fd, unsigned short flags, struct Gpm_Type *type,
+		       int argc, char **argv)
 {
-  int i;
-  int id;
-  static unsigned char basic_init[] = { GPM_AUX_ENABLE_DEV, GPM_AUX_SET_SAMPLE, 100 };
-  static unsigned char imps2_init[] = { GPM_AUX_SET_SAMPLE, 200, GPM_AUX_SET_SAMPLE, 100, GPM_AUX_SET_SAMPLE, 80, };
-  static unsigned char ps2_init[] = { GPM_AUX_SET_SCALE11, GPM_AUX_ENABLE_DEV, GPM_AUX_SET_SAMPLE, 100, GPM_AUX_SET_RES, 3, };
-
-  /* Do a basic init in case the mouse is confused */
-  write_to_mouse(fd, basic_init, sizeof (basic_init));
-
-  /* Now try again and make sure we have a PS/2 mouse */
-  if (write_to_mouse(fd, basic_init, sizeof (basic_init)) != 0) {
-    gpm_debug_log(LOG_ERR, "imps2: PS/2 mouse failed init");
-    return(NULL);
-  }
+  int i, id, error = 0, rate;
 
-  /* Try to switch to 3 button mode */
-  if (write_to_mouse(fd, imps2_init, sizeof (imps2_init)) != 0) {
-    gpm_debug_log(LOG_ERR, "imps2: PS/2 mouse failed (3 button) init");
+  /* Flush any existing input. */
+  tcflush (fd, TCIFLUSH);
+
+  if (write_ps2 (fd, GPM_AUX_DEFAULTS, '\0', 1, -1)) {
+    gpm_debug_log(LOG_ERR, "PS/2 mouse failed init");
     return(NULL);
   }
 
-  /* Read the mouse id */
-  id = read_mouse_id(fd);
-  if (id == GPM_AUX_ID_ERROR) {
-    gpm_debug_log(LOG_ERR, "imps2: PS/2 mouse failed to read id, assuming standard PS/2");
-    id = GPM_AUX_ID_PS2;
+  // Magic to enable the IMPS/2 protocol.
+  if (!strcmp(type->name, "imps2")) {
+    error += write_ps2 (fd, GPM_AUX_SET_SAMPLE, 200, 2, -1);
+    error += write_ps2 (fd, GPM_AUX_SET_SAMPLE, 100, 2, -1);
+    error += write_ps2 (fd, GPM_AUX_SET_SAMPLE, 80, 2, -1);
+    if (error) {
+      gpm_debug_log(LOG_ERR, "imps2: PS/2 mouse failed (3 button) init");
+      return(NULL);
+    }
+  } else if (!strcmp(type->name, "exps2")) {
+    error += write_ps2 (fd, GPM_AUX_SET_SAMPLE, 200, 2, -1);
+    error += write_ps2 (fd, GPM_AUX_SET_SAMPLE, 200, 2, -1);
+    error += write_ps2 (fd, GPM_AUX_SET_SAMPLE, 80, 2, -1);
+    if (error) {
+      gpm_debug_log (LOG_ERR, "exps2: PS/2 mouse failed (3 button) init");
+      return (NULL);
+    }
   }
 
-  /* And do the real initialisation */
-  if (write_to_mouse(fd, ps2_init, sizeof (ps2_init)) != 0) {
-    gpm_debug_log(LOG_ERR, "imps2: PS/2 mouse failed setup, continuing...");
+  if (write_ps2 (fd, GPM_AUX_SET_SCALE11, '\0', 1, -1)) {
+    gpm_debug_log(LOG_ERR, "PS/2 mouse failed init: Unable to set 1:1 scale.");
+    return (NULL);
   }
 
-  if (id == GPM_AUX_ID_IMPS2) {
-    /* Really an intellipoint, so initialise 3 button mode (4 byte packets) */
-    gpm_debug_log(LOG_NOTICE, "imps2: Auto-detected intellimouse PS/2");
-
-    return type;
+  if (opt_sample > 0) {
+    if (opt_sample >= 200) rate = 200;
+    else if (opt_sample >= 100) rate = 100;
+    else if (opt_sample >= 80) rate = 80;
+    else if (opt_sample >= 60) rate = 60;
+    else if (opt_sample >= 40) rate = 40;
+    else rate = 20;
+  } else {
+    rate = 100;
   }
-  if (id != GPM_AUX_ID_PS2) {
-    gpm_debug_log(LOG_ERR, "imps2: Auto-detected unknown mouse type %d, assuming standard PS/2", id);
-  }
-  else {
-    gpm_debug_log(LOG_NOTICE, "imps2: Auto-detected standard PS/2");
+
+  if (write_ps2 (fd, GPM_AUX_SET_SAMPLE, rate, 2, -1)) {
+    gpm_debug_log(LOG_ERR, "PS/2 mouse failed init: Unable to set rate.");
+    return (NULL);
   }
-  for (type=mice; type->fun; type++) {
-    if (strcmp(type->name, "ps2") == 0) {
-      return(type);
-    }
+
+  write_ps2 (fd, GPM_AUX_SET_STREAM, '\0', 1, 1);
+  return type;
+    
+  /* FIXME: We need to decide how to handle this. */
+#if 0
+  /* Read the mouse id */
+  id = read_mouse_id(fd);
+
+  switch (id) {
+    case GPM_AUX_ID_ERROR:
+      gpm_debug_log (LOG_ERR, "Unable to read PS/2 mouse ID: Using selected protocol.\n");
+      return type;
+    case GPM_AUX_ID_PS2:
+      gpm_debug_log(LOG_NOTICE, "PS/2 protocol mouse.");
+      return get_mouse_type("ps2");
+    case GPM_AUX_ID_IMPS2:
+      gpm_debug_log(LOG_NOTICE, "IMPS/2 protocol mouse.");
+      return get_mouse_type("imps2");
+    case GPM_AUX_ID_EXPS2:
+      gpm_debug_log(LOG_NOTICE, "EXPS/2 protocol mouse.");
+      return get_mouse_type("exps2");
+    default:
+      gpm_debug_log (LOG_ERR, "Unknown mouse ID, using selected protocol.");
+      return type;
   }
-  /* ps2 was not found!!! */
-  return(NULL);
+#endif
 }
 
 /*
@@ -2159,8 +2189,8 @@
                                 {0xf8, 0x80, 0x00, 0x00}, 3, 3, 0, 0, 0},
   {"ps2",  "For most busmice connected to a PS/2 port (round with 6 metal\n"
            "                     pins).",
-           "PS/2", M_ps2, I_empty, STD_FLG,
-                                {0xc0, 0x00, 0x00, 0x00}, 3, 1, 0, 0, 0},
+           "PS/2", M_ps2, I_ps2, STD_FLG,
+                                {0x08, 0x08, 0x00, 0x00}, 3, 1, 0, 0, 0},
   {"ncr",  "Ncr3125pen, found on some laptops",
            "", M_ncr, NULL, STD_FLG,
                                 {0x08, 0x08, 0x00, 0x00}, 7, 7, 0, 1, 0},
@@ -2180,12 +2210,11 @@
                                 {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0},
   {"imps2","For the Microsoft IntelliMouse on a PS/2 port (round\n"
            "                     connector with 6 pins), 3 buttons (wheel is repeated).",
-
-           "", M_imps2, I_imps2, STD_FLG,
-                                {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0},
+           "", M_imps2, I_ps2, STD_FLG,
+                                {0x08, 0x08, 0x00, 0x00}, 4, 1, 0, 0, 0},
   {"exps2",   "IntelliMouse Explorer (ps2) - 3 buttons, wheel unused",
-           "ExplorerPS/2", M_ps2, I_exps2, STD_FLG,
-                                {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0},
+           "ExplorerPS/2", M_ps2, I_ps2, STD_FLG,
+                                {0x08, 0x08, 0x00, 0x00}, 4, 1, 0, 0, 0},
   {"ms3",  "For the Microsoft IntelliMouse (serial), 3 buttons (wheel is repeated).",
            "", M_ms3, I_pnp, CS7 | STD_FLG,
                                 {0xc0, 0x40, 0xc0, 0x00}, 4, 1, 0, 0, R_ms3},
