diff -u b/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- b/Documentation/kernel-parameters.txt	2005-02-28 17:23:09 -08:00
+++ b/Documentation/kernel-parameters.txt	2005-02-28 17:20:10 -08:00
@@ -515,11 +515,11 @@
 	i8042.dumbkbd	[HW] Pretend that controlled can only read data from
 			     keyboard and can not control its state
 			     (Don't attempt to blink the leds)
+	i8042.noacpi	[HW] Don't use ACPI to discover KBD/AUX controller
+			     settings
 	i8042.noaux	[HW] Don't check for auxiliary (== mouse) port
 	i8042.nomux	[HW] Don't check presence of an active multiplexing
 			     controller
-	i8042.nopnp	[HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
-			     controllers
 	i8042.panicblink=
 			[HW] Frequency with which keyboard LEDs should blink
 			     when kernel panics (default is 0.5 sec)
diff -u b/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- b/drivers/char/keyboard.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/char/keyboard.c	2005-02-28 17:20:10 -08:00
@@ -141,7 +141,7 @@
 /* Simple translation table for the SysRq keys */
 
 #ifdef CONFIG_MAGIC_SYSRQ
-unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
+unsigned char kbd_sysrq_xlate[KEY_MAX] =
         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
@@ -199,6 +199,4 @@
 	if (scancode >= dev->keycodemax)
 		return -EINVAL;
-	if (keycode > KEY_MAX)
-		return -EINVAL;
 	if (keycode < 0 || keycode > KEY_MAX)
 		return -EINVAL;
@@ -933,7 +931,7 @@
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
     defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\
     defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
-    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
+    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_RPC))
 
 #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
 			((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
diff -u b/drivers/input/evdev.c b/drivers/input/evdev.c
--- b/drivers/input/evdev.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/evdev.c	2005-02-28 17:20:10 -08:00
@@ -225,15 +225,14 @@
 
 		case EVIOCGKEYCODE:
 			if (get_user(t, ip)) return -EFAULT;
-			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
+			if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
 			if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) return -EFAULT;
 			return 0;
 
 		case EVIOCSKEYCODE:
 			if (get_user(t, ip)) return -EFAULT;
-			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
+			if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
 			if (get_user(v, ip + 1)) return -EFAULT;
-			if (v < 0 || v > KEY_MAX) return -EINVAL;
 			u = SET_INPUT_KEYCODE(dev, t, v);
 			clear_bit(u, dev->keybit);
 			set_bit(v, dev->keybit);
diff -u b/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
--- b/drivers/input/gameport/gameport.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/gameport/gameport.c	2005-02-28 17:20:09 -08:00
@@ -39,8 +39,6 @@
 EXPORT_SYMBOL(gameport_cooked_read);
 EXPORT_SYMBOL(gameport_set_name);
 EXPORT_SYMBOL(gameport_set_phys);
-EXPORT_SYMBOL(gameport_start_polling);
-EXPORT_SYMBOL(gameport_stop_polling);
 
 /*
  * gameport_sem protects entire gameport subsystem and is taken
@@ -59,7 +57,7 @@
 static void gameport_reconnect_port(struct gameport *gameport);
 static void gameport_disconnect_port(struct gameport *gameport);
 
-#if defined(__i386__)
+#ifdef __i386__
 
 #define DELTA(x,y)      ((y)-(x)+((y)<(x)?1193182/HZ:0))
 #define GET_TIME(x)     do { x = get_time_pit(); } while (0)
@@ -81,15 +79,13 @@
 
 #endif
 
-
-
 /*
  * gameport_measure_speed() measures the gameport i/o speed.
  */
 
 static int gameport_measure_speed(struct gameport *gameport)
 {
-#if defined(__i386__)
+#ifdef __i386__
 
 	unsigned int i, t, t1, t2, t3, tx;
 	unsigned long flags;
@@ -102,7 +98,7 @@
 	for(i = 0; i < 50; i++) {
 		local_irq_save(flags);
 		GET_TIME(t1);
-		for (t = 0; t < 50; t++) gameport_read(gameport);
+		for(t = 0; t < 50; t++) gameport_read(gameport);
 		GET_TIME(t2);
 		GET_TIME(t3);
 		local_irq_restore(flags);
@@ -113,36 +109,10 @@
 	gameport_close(gameport);
 	return 59659 / (tx < 1 ? 1 : tx);
 
-#elif defined (__x86_64__)
-
-	unsigned int i, t;
-	unsigned long tx, t1, t2, flags;
-
-	if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
-		return 0;
-
-	tx = 1 << 30;
-
-	for(i = 0; i < 50; i++) {
-		local_irq_save(flags);
-		rdtscl(t1);
-		for (t = 0; t < 50; t++) gameport_read(gameport);
-		rdtscl(t2);
-		local_irq_restore(flags);
-		udelay(i * 10);
-		if (t2 - t1 < tx) tx = t2 - t1;
-	}
-
-	gameport_close(gameport);
-	return (cpu_data[_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
-
 #else
 
 	unsigned int j, t = 0;
 
-	if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
-		return 0;
-
 	j = jiffies; while (j == jiffies);
 	j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); }
 
@@ -152,37 +122,6 @@
 #endif
 }
 
-void gameport_start_polling(struct gameport *gameport)
-{
-	spin_lock(&gameport->timer_lock);
-
-	if (!gameport->poll_cnt++) {
-		BUG_ON(!gameport->poll_handler);
-		BUG_ON(!gameport->poll_interval);
-		mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval));
-	}
-
-	spin_unlock(&gameport->timer_lock);
-}
-
-void gameport_stop_polling(struct gameport *gameport)
-{
-	spin_lock(&gameport->timer_lock);
-
-	if (!--gameport->poll_cnt)
-		del_timer(&gameport->poll_timer);
-
-	spin_unlock(&gameport->timer_lock);
-}
-
-static void gameport_run_poll_handler(unsigned long d)
-{
-	struct gameport *gameport = (struct gameport *)d;
-
-	gameport->poll_handler(gameport);
-	if (gameport->poll_cnt)
-		mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval));
-}
 
 /*
  * Basic gameport -> driver core mappings
@@ -530,11 +469,6 @@
 	gameport->dev.release = gameport_release_port;
 	if (gameport->parent)
 		gameport->dev.parent = &gameport->parent->dev;
-
-	spin_lock_init(&gameport->timer_lock);
-	init_timer(&gameport->poll_timer);
-	gameport->poll_timer.function = gameport_run_poll_handler;
-	gameport->poll_timer.data = (unsigned long)gameport;
 }
 
 /*
@@ -763,9 +697,6 @@
 
 void gameport_close(struct gameport *gameport)
 {
-	del_timer_sync(&gameport->poll_timer);
-	gameport->poll_handler = NULL;
-	gameport->poll_interval = 0;
 	gameport_set_drv(gameport, NULL);
 	if (gameport->close)
 		gameport->close(gameport);
diff -u b/drivers/input/input.c b/drivers/input/input.c
--- b/drivers/input/input.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/input.c	2005-02-28 17:20:09 -08:00
@@ -47,7 +47,6 @@
 static LIST_HEAD(input_handler_list);
 
 static struct input_handler *input_table[8];
-static atomic_t input_device_num = ATOMIC_INIT(0);
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *proc_bus_input_dir;
@@ -326,27 +325,52 @@
 			SPRINTF_BIT_A(bit, name, max); \
 	} while (0)
 
-static int __input_hotplug(struct input_dev *dev, char **envp, int num_envp,
-			   char *buffer, int buffer_size)
+static void input_call_hotplug(char *verb, struct input_dev *dev)
 {
-	char *scratch;
-	int i = 0, j;
-	scratch = buffer;
+	char *argv[3], **envp, *buf, *scratch;
+	int i = 0, j, value;
 
-	if (!dev)
-		return -ENODEV;
+	if (!hotplug_path[0]) {
+		printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n");
+		return;
+	}
+	if (in_interrupt()) {
+		printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
+		return;
+	}
+	if (!current->fs->root) {
+		printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
+		return;
+	}
+	if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
+		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
+		return;
+	}
+	if (!(buf = kmalloc(1024, GFP_KERNEL))) {
+		kfree (envp);
+		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
+		return;
+	}
+
+	argv[0] = hotplug_path;
+	argv[1] = "input";
+	argv[2] = NULL;
+
+	envp[i++] = "HOME=/";
+	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+
+	scratch = buf;
+
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
 
 	envp[i++] = scratch;
 	scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
 		dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
 
-#ifdef INPUT_DEBUG
-	printk(KERN_DEBUG "%s: PRODUCT %x/%x/%x/%x\n", __FUNCTION__,
-	       dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
-#endif
 	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) {
@@ -365,122 +389,23 @@
 
 	envp[i++] = NULL;
 
-	return 0;
-}
-
-int input_hotplug(struct class_device *cdev, char **envp, int num_envp,
-		  char *buffer, int buffer_size)
-{
-	struct input_dev *dev;
-
-	if (!cdev)
-		return -ENODEV;
 #ifdef INPUT_DEBUG
-	printk(KERN_DEBUG "%s: entered for dev %p\n", __FUNCTION__, 
-	       &cdev->dev);
+	printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n",
+		argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]);
 #endif
 
-	dev = container_of(cdev,struct input_dev,cdev);
+	value = call_usermodehelper(argv [0], argv, envp, 0);
 
-	return __input_hotplug(dev, envp, num_envp, buffer, buffer_size);
-}
+	kfree(buf);
+	kfree(envp);
 
+#ifdef INPUT_DEBUG
+	if (value != 0)
+		printk(KERN_DEBUG "input.c: hotplug returned %d\n", value);
 #endif
-
-#define INPUT_ATTR_BIT_B(bit, max) \
-	do { \
-		for (i = NBITS(max) - 1; i >= 0; i--) \
-			if (dev->bit[i]) break; \
-		for (; i >= 0; i--) \
-			len += sprintf(buf + len, "%lx ", dev->bit[i]); \
-		if (len) len += sprintf(buf + len, "\n"); \
-	} while (0)
-
-#define INPUT_ATTR_BIT_B2(bit, max, ev) \
-	do { \
-		if (test_bit(ev, dev->evbit)) \
-			INPUT_ATTR_BIT_B(bit, max); \
-	} while (0)
-
-
-static ssize_t input_class_show_ev(struct class_device *class_dev, char *buf)
-{
-	struct input_dev *dev = container_of(class_dev, struct input_dev,cdev);
-	int i, len = 0;
-
-	INPUT_ATTR_BIT_B(evbit, EV_MAX);
-	return len;
-}
-
-#define INPUT_CLASS_ATTR_BIT(_name,_bit) \
-static ssize_t input_class_show_##_bit(struct class_device *class_dev, \
-				       char *buf) \
-{ \
-	struct input_dev *dev = container_of(class_dev,struct input_dev,cdev); \
-        int i, len = 0; \
-\
-	INPUT_ATTR_BIT_B2(_bit##bit, _name##_MAX, EV_##_name); \
-	return len; \
 }
 
-INPUT_CLASS_ATTR_BIT(KEY,key)
-INPUT_CLASS_ATTR_BIT(REL,rel)
-INPUT_CLASS_ATTR_BIT(ABS,abs)
-INPUT_CLASS_ATTR_BIT(MSC,msc)
-INPUT_CLASS_ATTR_BIT(LED,led)
-INPUT_CLASS_ATTR_BIT(SND,snd)
-INPUT_CLASS_ATTR_BIT(FF,ff)
-
-static ssize_t input_class_show_phys(struct class_device *class_dev, char *buf)
-{
-	struct input_dev *dev = container_of(class_dev,struct input_dev,cdev);
-
-	return sprintf(buf, "%s\n", dev->phys ? dev->phys : "(none)" );
-}
-
-static ssize_t input_class_show_name(struct class_device *class_dev, char *buf)
-{
-	struct input_dev *dev = container_of(class_dev,struct input_dev,cdev);
-
-	return sprintf(buf, "%s\n", dev->name ? dev->name : "(none)" );
-}
-
-static ssize_t input_class_show_product(struct class_device *class_dev, char *buf)
-{
-	struct input_dev *dev = container_of(class_dev,struct input_dev,cdev);
-
-	return sprintf(buf, "%x/%x/%x/%x\n", dev->id.bustype, dev->id.vendor, 
-		       dev->id.product, dev->id.version);
-}
-
-static struct class_device_attribute input_device_class_attrs[] = {
-	__ATTR( product, S_IRUGO, input_class_show_product, NULL) ,
-	__ATTR( phys, S_IRUGO, input_class_show_phys, NULL ),
-	__ATTR( name, S_IRUGO, input_class_show_name, NULL) ,
-	__ATTR( ev, S_IRUGO, input_class_show_ev, NULL) ,
-	__ATTR( key, S_IRUGO, input_class_show_key, NULL) ,
-	__ATTR( rel, S_IRUGO, input_class_show_rel, NULL) ,
-	__ATTR( abs, S_IRUGO, input_class_show_abs, NULL) ,
-	__ATTR( msc, S_IRUGO, input_class_show_msc, NULL) ,
-	__ATTR( led, S_IRUGO, input_class_show_led, NULL) ,
-	__ATTR( snd, S_IRUGO, input_class_show_snd, NULL) ,
-	__ATTR( ff, S_IRUGO, input_class_show_ff, NULL) ,
-	__ATTR_NULL,
-};
-
-static void input_device_class_release( struct class_device *class_dev )
-{
-	put_device(class_dev->dev);
-}
-
-static struct class input_device_class = {
-	.name =		"input_device",
-#ifdef CONFIG_HOTPLUG
-	.hotplug = 	input_hotplug,
 #endif
-	.release = 	input_device_class_release,
-	.class_dev_attrs = input_device_class_attrs,
-};
 
 void input_register_device(struct input_dev *dev)
 {
@@ -488,18 +413,6 @@
 	struct input_handler *handler;
 	struct input_device_id *id;
 
-	dev->cdev.class = &input_device_class;
-	
-	dev->cdev.dev = get_device(dev->dev);
-	sprintf(dev->cdev.class_id, "input%d", 
-		atomic_inc_return(&input_device_num));
-
-	if (class_device_register(&dev->cdev)) {
-		if (dev->dev)
-			put_device(dev->dev);
-		return;
-	}
-
 	set_bit(EV_SYN, dev->evbit);
 
 	/*
@@ -524,6 +437,10 @@
 				if ((handle = handler->connect(handler, dev, id)))
 					input_link_handle(handle);
 
+#ifdef CONFIG_HOTPLUG
+	input_call_hotplug("add", dev);
+#endif
+
 #ifdef CONFIG_PROC_FS
 	input_devices_state++;
 	wake_up(&input_devices_poll_wait);
@@ -545,9 +462,11 @@
 		handle->handler->disconnect(handle);
 	}
 
-	list_del_init(&dev->node);
+#ifdef CONFIG_HOTPLUG
+	input_call_hotplug("remove", dev);
+#endif
 
-	class_device_unregister(&dev->cdev);
+	list_del_init(&dev->node);
 
 #ifdef CONFIG_PROC_FS
 	input_devices_state++;
@@ -792,13 +711,6 @@
 	input_class = class_simple_create(THIS_MODULE, "input");
 	if (IS_ERR(input_class))
 		return PTR_ERR(input_class);
-
-	retval = class_register(&input_device_class);
-	if (retval) {
-		class_simple_destroy(input_class);
-		return retval;
-	}
-
 	input_proc_init();
 	retval = register_chrdev(INPUT_MAJOR, "input", &input_fops);
 	if (retval) {
@@ -806,7 +718,6 @@
 		remove_proc_entry("devices", proc_bus_input_dir);
 		remove_proc_entry("handlers", proc_bus_input_dir);
 		remove_proc_entry("input", proc_bus);
-		class_unregister(&input_device_class);
 		class_simple_destroy(input_class);
 		return retval;
 	}
@@ -817,7 +728,6 @@
 		remove_proc_entry("handlers", proc_bus_input_dir);
 		remove_proc_entry("input", proc_bus);
 		unregister_chrdev(INPUT_MAJOR, "input");
-		class_unregister(&input_device_class);
 		class_simple_destroy(input_class);
 	}
 	return retval;
@@ -831,7 +741,6 @@
 
 	devfs_remove("input");
 	unregister_chrdev(INPUT_MAJOR, "input");
-	class_unregister(&input_device_class);
 	class_simple_destroy(input_class);
 }
 
diff -u b/drivers/input/joydev.c b/drivers/input/joydev.c
--- b/drivers/input/joydev.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joydev.c	2005-02-28 17:20:09 -08:00
@@ -47,15 +47,15 @@
 	struct input_handle handle;
 	wait_queue_head_t wait;
 	struct list_head list;
-	struct js_corr corr[ABS_MAX + 1];
+	struct js_corr corr[ABS_MAX];
 	struct JS_DATA_SAVE_TYPE glue;
 	int nabs;
 	int nkey;
-	__u16 keymap[KEY_MAX - BTN_MISC + 1];
-	__u16 keypam[KEY_MAX - BTN_MISC + 1];
-	__u8 absmap[ABS_MAX + 1];
-	__u8 abspam[ABS_MAX + 1];
-	__s16 abs[ABS_MAX + 1];
+	__u16 keymap[KEY_MAX - BTN_MISC];
+	__u16 keypam[KEY_MAX - BTN_MISC];
+	__u8 absmap[ABS_MAX];
+	__u8 abspam[ABS_MAX];
+	__s16 abs[ABS_MAX];
 };
 
 struct joydev_list {
@@ -337,7 +337,7 @@
 			return copy_to_user(argp, joydev->corr,
 						sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
 		case JSIOCSAXMAP:
-			if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
+			if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * ABS_MAX))
 				return -EFAULT;
 			for (i = 0; i < joydev->nabs; i++) {
 				if (joydev->abspam[i] > ABS_MAX) return -EINVAL;
@@ -346,9 +346,9 @@
 			return 0;
 		case JSIOCGAXMAP:
 			return copy_to_user(argp, joydev->abspam,
-						sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
+						sizeof(__u8) * ABS_MAX) ? -EFAULT : 0;
 		case JSIOCSBTNMAP:
-			if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
+			if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
 				return -EFAULT;
 			for (i = 0; i < joydev->nkey; i++) {
 				if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
@@ -357,7 +357,7 @@
 			return 0;
 		case JSIOCGBTNMAP:
 			return copy_to_user(argp, joydev->keypam,
-						sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
+						sizeof(__u16) * (KEY_MAX - BTN_MISC)) ? -EFAULT : 0;
 		default:
 			if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
 				int len;
@@ -408,21 +408,21 @@
 	joydev->handle.private = joydev;
 	sprintf(joydev->name, "js%d", minor);
 
-	for (i = 0; i < ABS_MAX + 1; i++)
+	for (i = 0; i < ABS_MAX; i++)
 		if (test_bit(i, dev->absbit)) {
 			joydev->absmap[i] = joydev->nabs;
 			joydev->abspam[joydev->nabs] = i;
 			joydev->nabs++;
 		}
 
-	for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC + 1; i++)
+	for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC; i++)
 		if (test_bit(i + BTN_MISC, dev->keybit)) {
 			joydev->keymap[i] = joydev->nkey;
 			joydev->keypam[joydev->nkey] = i + BTN_MISC;
 			joydev->nkey++;
 		}
 
-	for (i = 0; i < BTN_JOYSTICK - BTN_MISC + 1; i++)
+	for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++)
 		if (test_bit(i + BTN_MISC, dev->keybit)) {
 			joydev->keymap[i] = joydev->nkey;
 			joydev->keypam[joydev->nkey] = i + BTN_MISC;
diff -u b/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
--- b/drivers/input/joystick/a3d.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/joystick/a3d.c	2005-02-28 17:20:09 -08:00
@@ -41,9 +41,11 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-#define A3D_MAX_START		600	/* 600 us */
-#define A3D_MAX_STROBE		80	/* 80 us */
+#define A3D_MAX_START		400	/* 400 us */
+#define A3D_MAX_STROBE		60	/* 40 us */
+#define A3D_DELAY_READ		3	/* 3 ms */
 #define A3D_MAX_LENGTH		40	/* 40*3 bits */
+#define A3D_REFRESH_TIME	HZ/50	/* 20 ms */
 
 #define A3D_MODE_A3D		1	/* Assassin 3D */
 #define A3D_MODE_PAN		2	/* Panther */
@@ -57,10 +59,12 @@
 	struct gameport *gameport;
 	struct gameport *adc;
 	struct input_dev dev;
+	struct timer_list timer;
 	int axes[4];
 	int buttons;
 	int mode;
 	int length;
+	int used;
 	int reads;
 	int bads;
 	char phys[32];
@@ -174,20 +178,19 @@
 
 
 /*
- * a3d_poll() reads and analyzes A3D joystick data.
+ * a3d_timer() reads and analyzes A3D joystick data.
  */
 
-static void a3d_poll(struct gameport *gameport)
+static void a3d_timer(unsigned long private)
 {
-	struct a3d *a3d = gameport_get_drvdata(gameport);
+	struct a3d *a3d = (void *) private;
 	unsigned char data[A3D_MAX_LENGTH];
 
 	a3d->reads++;
-	if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length ||
-	    data[0] != a3d->mode || a3d_csum(data, a3d->length))
-	 	a3d->bads++;
-	else
-		a3d_read(a3d, data);
+	if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length
+		|| data[0] != a3d->mode || a3d_csum(data, a3d->length))
+	 	a3d->bads++; else a3d_read(a3d, data);
+	mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
 }
 
 /*
@@ -215,11 +218,10 @@
 static int a3d_adc_open(struct gameport *gameport, int mode)
 {
 	struct a3d *a3d = gameport->port_data;
-
 	if (mode != GAMEPORT_MODE_COOKED)
 		return -1;
-
-	gameport_start_polling(a3d->gameport);
+	if (!a3d->used++)
+		mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
 	return 0;
 }
 
@@ -231,7 +233,8 @@
 {
 	struct a3d *a3d = gameport->port_data;
 
-	gameport_stop_polling(a3d->gameport);
+	if (!--a3d->used)
+		del_timer(&a3d->timer);
 }
 
 /*
@@ -242,7 +245,8 @@
 {
 	struct a3d *a3d = dev->private;
 
-	gameport_start_polling(a3d->gameport);
+	if (!a3d->used++)
+		mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
 	return 0;
 }
 
@@ -254,7 +258,8 @@
 {
 	struct a3d *a3d = dev->private;
 
-	gameport_stop_polling(a3d->gameport);
+	if (!--a3d->used)
+		del_timer(&a3d->timer);
 }
 
 /*
@@ -273,6 +278,9 @@
 		return -ENOMEM;
 
 	a3d->gameport = gameport;
+	init_timer(&a3d->timer);
+	a3d->timer.data = (long) a3d;
+	a3d->timer.function = a3d_timer;
 
 	gameport_set_drvdata(gameport, a3d);
 
@@ -296,9 +304,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, a3d_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(a3d->phys, "%s/input0", gameport->phys);
 
 	if (a3d->mode == A3D_MODE_PXL) {
diff -u b/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
--- b/drivers/input/joystick/adi.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/joystick/adi.c	2005-02-28 17:20:09 -08:00
@@ -1,5 +1,7 @@
 /*
- *  Copyright (c) 1998-2005 Vojtech Pavlik
+ * $Id: adi.c,v 1.23 2002/01/22 20:26:17 vojtech Exp $
+ *
+ *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
 /*
@@ -47,6 +49,7 @@
 
 #define ADI_MAX_START		200	/* Trigger to packet timeout [200us] */
 #define ADI_MAX_STROBE		40	/* Single bit timeout [40us] */
+#define ADI_REFRESH_TIME	HZ/50	/* How often to poll the joystick [20 ms] */
 #define ADI_INIT_DELAY		10	/* Delay after init packet [10ms] */
 #define ADI_DATA_DELAY		4	/* Delay after data packet [4ms] */
 
@@ -56,7 +59,7 @@
 #define ADI_MIN_ID_LENGTH	66
 #define ADI_MAX_NAME_LENGTH	48
 #define ADI_MAX_CNAME_LENGTH	16
-#define ADI_MAX_PHYS_LENGTH	64
+#define ADI_MAX_PHYS_LENGTH	32
 
 #define ADI_FLAG_HAT		0x04
 #define ADI_FLAG_10BIT		0x08
@@ -126,9 +129,11 @@
 
 struct adi_port {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct adi adi[2];
 	int bad;
 	int reads;
+	int used;
 };
 
 /*
@@ -272,15 +277,15 @@
 }
 
 /*
- * adi_poll() repeatedly polls the Logitech joysticks.
+ * adi_timer() repeatedly polls the Logitech joysticks.
  */
 
-static void adi_poll(struct gameport *gameport)
+static void adi_timer(unsigned long data)
 {
-	struct adi_port *port = gameport_get_drvdata(gameport);
-
+	struct adi_port *port = (void *) data;
 	port->bad -= adi_read(port);
 	port->reads++;
+	mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
 }
 
 /*
@@ -290,8 +295,8 @@
 static int adi_open(struct input_dev *dev)
 {
 	struct adi_port *port = dev->private;
-
-	gameport_start_polling(port->gameport);
+	if (!port->used++)
+		mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
 	return 0;
 }
 
@@ -302,8 +307,8 @@
 static void adi_close(struct input_dev *dev)
 {
 	struct adi_port *port = dev->private;
-
-	gameport_stop_polling(port->gameport);
+	if (!--port->used)
+		del_timer(&port->timer);
 }
 
 /*
@@ -313,16 +318,13 @@
 
 static void adi_init_digital(struct gameport *gameport)
 {
-	int seq[] = { 4, -2, -3, 10, -6, -11, -7, -9, 11, 0 };
+	int seq[] = { 3, -2, -3, 10, -6, -11, -7, -9, 11, 0 };
 	int i;
 
 	for (i = 0; seq[i]; i++) {
 		gameport_trigger(gameport);
 		if (seq[i] > 0) msleep(seq[i]);
-		if (seq[i] < 0) {
-			mdelay(-seq[i]);
-			udelay(-seq[i]*14);	/* It looks like mdelay() is off by approx 1.4% */
-		}
+		if (seq[i] < 0) mdelay(-seq[i]);
 	}
 }
 
@@ -408,9 +410,9 @@
 
 	t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX;
 
-	snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id);
-	snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf);
-	snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half);
+	sprintf(buf, adi_names[t], adi->id);
+	sprintf(adi->name, "Logitech %s", buf);
+	sprintf(adi->phys, "%s/input%d", port->gameport->phys, half);
 
 	adi->abs = adi_abs[t];
 	adi->key = adi_key[t];
@@ -473,6 +475,9 @@
 		return -ENOMEM;
 
 	port->gameport = gameport;
+	init_timer(&port->timer);
+	port->timer.data = (long) port;
+	port->timer.function = adi_timer;
 
 	gameport_set_drvdata(gameport, port);
 
@@ -499,9 +504,6 @@
 		return -ENODEV;
 	}
 
-	gameport_set_poll_handler(gameport, adi_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	msleep(ADI_INIT_DELAY);
 	if (adi_read(port)) {
 		msleep(ADI_DATA_DELAY);
diff -u b/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
--- b/drivers/input/joystick/analog.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/analog.c	2005-02-28 17:20:10 -08:00
@@ -90,6 +90,7 @@
 
 #define ANALOG_MAX_TIME		3	/* 3 ms */
 #define ANALOG_LOOP_TIME	2000	/* 2 * loop */
+#define ANALOG_REFRESH_TIME	HZ/100	/* 10 ms */
 #define ANALOG_SAITEK_DELAY	200	/* 200 us */
 #define ANALOG_SAITEK_TIME	2000	/* 2000 us */
 #define ANALOG_AXIS_TIME	2	/* 2 * refresh */
@@ -120,6 +121,7 @@
 
 struct analog_port {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct analog analog[2];
 	unsigned char mask;
 	char saitek;
@@ -132,6 +134,7 @@
 	int axes[4];
 	int buttons;
 	int initial[4];
+	int used;
 	int axtime;
 };
 
@@ -304,12 +307,12 @@
 }
 
 /*
- * analog_poll() repeatedly polls the Analog joysticks.
+ * analog_timer() repeatedly polls the Analog joysticks.
  */
 
-static void analog_poll(struct gameport *gameport)
+static void analog_timer(unsigned long data)
 {
-	struct analog_port *port = gameport_get_drvdata(gameport);
+	struct analog_port *port = (void *) data;
 	int i;
 
 	char saitek = !!(port->analog[0].mask & ANALOG_SAITEK);
@@ -335,6 +338,8 @@
 	for (i = 0; i < 2; i++)
 		if (port->analog[i].mask)
 			analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
+
+	mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
 }
 
 /*
@@ -344,8 +349,8 @@
 static int analog_open(struct input_dev *dev)
 {
 	struct analog_port *port = dev->private;
-
-	gameport_start_polling(port->gameport);
+	if (!port->used++)
+		mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
 	return 0;
 }
 
@@ -356,8 +361,8 @@
 static void analog_close(struct input_dev *dev)
 {
 	struct analog_port *port = dev->private;
-
-	gameport_stop_polling(port->gameport);
+	if (!--port->used)
+		del_timer(&port->timer);
 }
 
 /*
@@ -376,7 +381,7 @@
 #ifdef FAKE_TIME
 	analog_faketime += 830;
 #endif
-	mdelay(1);
+	udelay(1000);
 	GET_TIME(t2);
 	GET_TIME(t3);
 	local_irq_restore(flags);
@@ -589,6 +594,9 @@
 	int i, t, u, v;
 
 	port->gameport = gameport;
+	init_timer(&port->timer);
+	port->timer.data = (long) port;
+	port->timer.function = analog_timer;
 
 	gameport_set_drvdata(gameport, port);
 
@@ -670,9 +678,6 @@
 		return err;
 	}
 
-	gameport_set_poll_handler(gameport, analog_poll);
-	gameport_set_poll_interval(gameport, 10);
-
 	for (i = 0; i < 2; i++)
 		if (port->analog[i].mask)
 			analog_init_device(port, port->analog + i, i);
diff -u b/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
--- b/drivers/input/joystick/cobra.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/cobra.c	2005-02-28 17:20:09 -08:00
@@ -42,6 +42,7 @@
 MODULE_LICENSE("GPL");
 
 #define COBRA_MAX_STROBE	45	/* 45 us max wait for first strobe */
+#define COBRA_REFRESH_TIME	HZ/50	/* 20 ms between reads */
 #define COBRA_LENGTH		36
 
 static char* cobra_name = "Creative Labs Blaster GamePad Cobra";
@@ -50,7 +51,9 @@
 
 struct cobra {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[2];
+	int used;
 	int reads;
 	int bads;
 	unsigned char exists;
@@ -111,19 +114,18 @@
 	return ret;
 }
 
-static void cobra_poll(struct gameport *gameport)
+static void cobra_timer(unsigned long private)
 {
-	struct cobra *cobra = gameport_get_drvdata(gameport);
+	struct cobra *cobra = (void *) private;
 	struct input_dev *dev;
 	unsigned int data[2];
 	int i, j, r;
 
 	cobra->reads++;
 
-	if ((r = cobra_read_packet(gameport, data)) != cobra->exists) {
+	if ((r = cobra_read_packet(cobra->gameport, data)) != cobra->exists)
 		cobra->bads++;
-		return;
-	}
+	else
 
 	for (i = 0; i < 2; i++)
 		if (cobra->exists & r & (1 << i)) {
@@ -139,21 +141,23 @@
 			input_sync(dev);
 
 		}
+
+	mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
 }
 
 static int cobra_open(struct input_dev *dev)
 {
 	struct cobra *cobra = dev->private;
-
-	gameport_start_polling(cobra->gameport);
+	if (!cobra->used++)
+		mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
 	return 0;
 }
 
 static void cobra_close(struct input_dev *dev)
 {
 	struct cobra *cobra = dev->private;
-
-	gameport_stop_polling(cobra->gameport);
+	if (!--cobra->used)
+		del_timer(&cobra->timer);
 }
 
 static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
@@ -167,6 +171,9 @@
 		return -ENOMEM;
 
 	cobra->gameport = gameport;
+	init_timer(&cobra->timer);
+	cobra->timer.data = (long) cobra;
+	cobra->timer.function = cobra_timer;
 
 	gameport_set_drvdata(gameport, cobra);
 
@@ -189,7 +196,4 @@
 	}
 
-	gameport_set_poll_handler(gameport, cobra_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	for (i = 0; i < 2; i++)
 		if ((cobra->exists >> i) & 1) {
diff -u b/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
--- b/drivers/input/joystick/gf2k.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/gf2k.c	2005-02-28 17:20:09 -08:00
@@ -46,6 +46,7 @@
 #define GF2K_STROBE		40	/* The time we wait for the first bit [40 us] */
 #define GF2K_TIMEOUT		4	/* Wait for everything to settle [4 ms] */
 #define GF2K_LENGTH		80	/* Max number of triplets in a packet */
+#define GF2K_REFRESH		HZ/50	/* Time between joystick polls [20 ms] */
 
 /*
  * Genius joystick ids ...
@@ -81,9 +82,11 @@
 
 struct gf2k {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev;
 	int reads;
 	int bads;
+	int used;
 	unsigned char id;
 	unsigned char length;
 	char phys[32];
@@ -201,35 +204,36 @@
 }
 
 /*
- * gf2k_poll() reads and analyzes Genius joystick data.
+ * gf2k_timer() reads and analyzes Genius joystick data.
  */
 
-static void gf2k_poll(struct gameport *gameport)
+static void gf2k_timer(unsigned long private)
 {
-	struct gf2k *gf2k = gameport_get_drvdata(gameport);
+	struct gf2k *gf2k = (void *) private;
 	unsigned char data[GF2K_LENGTH];
 
 	gf2k->reads++;
 
-	if (gf2k_read_packet(gf2k->gameport, gf2k_length[gf2k->id], data) < gf2k_length[gf2k->id])
+	if (gf2k_read_packet(gf2k->gameport, gf2k_length[gf2k->id], data) < gf2k_length[gf2k->id]) {
 		gf2k->bads++;
-	else
-		gf2k_read(gf2k, data);
+	} else gf2k_read(gf2k, data);
+
+	mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
 }
 
 static int gf2k_open(struct input_dev *dev)
 {
 	struct gf2k *gf2k = dev->private;
-
-	gameport_start_polling(gf2k->gameport);
+	if (!gf2k->used++)
+		mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
 	return 0;
 }
 
 static void gf2k_close(struct input_dev *dev)
 {
 	struct gf2k *gf2k = dev->private;
-
-	gameport_stop_polling(gf2k->gameport);
+	if (!--gf2k->used)
+		del_timer(&gf2k->timer);
 }
 
 /*
@@ -246,6 +250,9 @@
 		return -ENOMEM;
 
 	gf2k->gameport = gameport;
+	init_timer(&gf2k->timer);
+	gf2k->timer.data = (long) gf2k;
+	gf2k->timer.function = gf2k_timer;
 
 	gameport_set_drvdata(gameport, gf2k);
 
@@ -288,9 +295,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, gf2k_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(gf2k->phys, "%s/input0", gameport->phys);
 
 	gf2k->length = gf2k_lens[gf2k->id];
diff -u b/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
--- b/drivers/input/joystick/grip.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/joystick/grip.c	2005-02-28 17:20:09 -08:00
@@ -53,10 +53,14 @@
 #define GRIP_MAX_CHUNKS_XT	10
 #define GRIP_MAX_BITS_XT	30
 
+#define GRIP_REFRESH_TIME	HZ/50	/* 20 ms */
+
 struct grip {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[2];
 	unsigned char mode[2];
+	int used;
 	int reads;
 	int bads;
 	char phys[2][32];
@@ -181,9 +185,9 @@
  * grip_timer() repeatedly polls the joysticks and generates events.
  */
 
-static void grip_poll(struct gameport *gameport)
+static void grip_timer(unsigned long private)
 {
-	struct grip *grip = gameport_get_drvdata(gameport);
+	struct grip *grip = (void*) private;
 	unsigned int data[GRIP_LENGTH_XT];
 	struct input_dev *dev;
 	int i, j;
@@ -277,21 +281,23 @@
 
 		input_sync(dev);
 	}
+
+	mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
 }
 
 static int grip_open(struct input_dev *dev)
 {
 	struct grip *grip = dev->private;
-
-	gameport_start_polling(grip->gameport);
+	if (!grip->used++)
+		mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
 	return 0;
 }
 
 static void grip_close(struct input_dev *dev)
 {
 	struct grip *grip = dev->private;
-
-	gameport_stop_polling(grip->gameport);
+	if (!--grip->used)
+		del_timer(&grip->timer);
 }
 
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
@@ -305,6 +311,9 @@
 		return -ENOMEM;
 
 	grip->gameport = gameport;
+	init_timer(&grip->timer);
+	grip->timer.data = (long) grip;
+	grip->timer.function = grip_timer;
 
 	gameport_set_drvdata(gameport, grip);
 
@@ -337,7 +346,4 @@
 	}
 
-	gameport_set_poll_handler(gameport, grip_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	for (i = 0; i < 2; i++)
 		if (grip->mode[i]) {
diff -u b/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
--- b/drivers/input/joystick/grip_mp.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/grip_mp.c	2005-02-28 17:20:10 -08:00
@@ -38,9 +38,11 @@
 
 struct grip_mp {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[4];
 	int mode[4];
 	int registered[4];
+	int used;
 	int reads;
 	int bads;
 
@@ -79,6 +81,7 @@
  */
 
 #define GRIP_INIT_DELAY         2000          /*  2 ms */
+#define GRIP_REFRESH_TIME       HZ/50	      /* 20 ms */
 
 #define GRIP_MODE_NONE		0
 #define GRIP_MODE_RESET         1
@@ -523,9 +526,8 @@
  * Get the multiport state.
  */
 
-static void grip_poll(struct gameport *gameport)
+static void get_and_report_mp_state(struct grip_mp *grip)
 {
-	struct grip_mp *grip = gameport_get_drvdata(gameport);
 	int i, npkts, flags;
 
 	for (npkts = 0; npkts < 4; npkts++) {
@@ -552,7 +554,8 @@
 {
 	struct grip_mp *grip = dev->private;
 
-	gameport_start_polling(grip->gameport);
+	if (!grip->used++)
+		mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
 	return 0;
 }
 
@@ -564,7 +567,8 @@
 {
 	struct grip_mp *grip = dev->private;
 
-	gameport_start_polling(grip->gameport);
+	if (!--grip->used)
+		del_timer(&grip->timer);
 }
 
 /*
@@ -602,6 +606,18 @@
 	       grip_name[grip->mode[slot]], slot);
 }
 
+/*
+ * Repeatedly polls the multiport and generates events.
+ */
+
+static void grip_timer(unsigned long private)
+{
+	struct grip_mp *grip = (void*) private;
+
+	get_and_report_mp_state(grip);
+	mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME);
+}
+
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct grip_mp *grip;
@@ -611,6 +627,9 @@
 		return -ENOMEM;
 
 	grip->gameport = gameport;
+	init_timer(&grip->timer);
+	grip->timer.data = (long) grip;
+	grip->timer.function = grip_timer;
 
 	gameport_set_drvdata(gameport, grip);
 
@@ -618,9 +637,6 @@
 	if (err)
 		goto fail1;
 
-	gameport_set_poll_handler(gameport, grip_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	if (!multiport_init(grip)) {
 		err = -ENODEV;
 		goto fail2;
diff -u b/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
--- b/drivers/input/joystick/guillemot.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/joystick/guillemot.c	2005-02-28 17:20:09 -08:00
@@ -45,6 +45,7 @@
 #define GUILLEMOT_MAX_START	600	/* 600 us */
 #define GUILLEMOT_MAX_STROBE	60	/* 60 us */
 #define GUILLEMOT_MAX_LENGTH	17	/* 17 bytes */
+#define GUILLEMOT_REFRESH_TIME	HZ/50	/* 20 ms */
 
 static short guillemot_abs_pad[] =
 	{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };
@@ -68,6 +69,8 @@
 struct guillemot {
 	struct gameport *gameport;
 	struct input_dev dev;
+	struct timer_list timer;
+	int used;
 	int bads;
 	int reads;
 	struct guillemot_type *type;
@@ -117,12 +120,12 @@
 }
 
 /*
- * guillemot_poll() reads and analyzes Guillemot joystick data.
+ * guillemot_timer() reads and analyzes Guillemot joystick data.
  */
 
-static void guillemot_poll(struct gameport *gameport)
+static void guillemot_timer(unsigned long private)
 {
-	struct guillemot *guillemot = gameport_get_drvdata(gameport);
+	struct guillemot *guillemot = (struct guillemot *) private;
 	struct input_dev *dev = &guillemot->dev;
 	u8 data[GUILLEMOT_MAX_LENGTH];
 	int i;
@@ -147,6 +150,8 @@
 	}
 
 	input_sync(dev);
+
+	mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
 }
 
 /*
@@ -157,7 +162,8 @@
 {
 	struct guillemot *guillemot = dev->private;
 
-	gameport_start_polling(guillemot->gameport);
+	if (!guillemot->used++)
+		mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
 	return 0;
 }
 
@@ -169,7 +175,8 @@
 {
 	struct guillemot *guillemot = dev->private;
 
-	gameport_stop_polling(guillemot->gameport);
+	if (!--guillemot->used)
+		del_timer(&guillemot->timer);
 }
 
 /*
@@ -187,6 +194,9 @@
 		return -ENOMEM;
 
 	guillemot->gameport = gameport;
+	init_timer(&guillemot->timer);
+	guillemot->timer.data = (long) guillemot;
+	guillemot->timer.function = guillemot_timer;
 
 	gameport_set_drvdata(gameport, guillemot);
 
@@ -212,9 +222,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, guillemot_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(guillemot->phys, "%s/input0", gameport->phys);
 
 	guillemot->type = guillemot_type + i;
diff -u b/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
--- b/drivers/input/joystick/interact.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/interact.c	2005-02-28 17:20:09 -08:00
@@ -45,9 +45,10 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-#define INTERACT_MAX_START	600	/* 400 us */
-#define INTERACT_MAX_STROBE	60	/* 40 us */
+#define INTERACT_MAX_START	400	/* 400 us */
+#define INTERACT_MAX_STROBE	40	/* 40 us */
 #define INTERACT_MAX_LENGTH	32	/* 32 bits */
+#define INTERACT_REFRESH_TIME	HZ/50	/* 20 ms */
 
 #define INTERACT_TYPE_HHFX	0	/* HammerHead/FX */
 #define INTERACT_TYPE_PP8D	1	/* ProPad 8 */
@@ -55,6 +56,8 @@
 struct interact {
 	struct gameport *gameport;
 	struct input_dev dev;
+	struct timer_list timer;
+	int used;
 	int bads;
 	int reads;
 	unsigned char type;
@@ -124,12 +127,12 @@
 }
 
 /*
- * interact_poll() reads and analyzes InterAct joystick data.
+ * interact_timer() reads and analyzes InterAct joystick data.
  */
 
-static void interact_poll(struct gameport *gameport)
+static void interact_timer(unsigned long private)
 {
-	struct interact *interact = gameport_get_drvdata(gameport);
+	struct interact *interact = (struct interact *) private;
 	struct input_dev *dev = &interact->dev;
 	u32 data[3];
 	int i;
@@ -176,6 +179,9 @@
 	}
 
 	input_sync(dev);
+
+	mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
+
 }
 
 /*
@@ -186,7 +192,8 @@
 {
 	struct interact *interact = dev->private;
 
-	gameport_start_polling(interact->gameport);
+	if (!interact->used++)
+		mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
 	return 0;
 }
 
@@ -198,7 +205,8 @@
 {
 	struct interact *interact = dev->private;
 
-	gameport_stop_polling(interact->gameport);
+	if (!--interact->used)
+		del_timer(&interact->timer);
 }
 
 /*
@@ -216,6 +224,9 @@
 		return -ENOMEM;
 
 	interact->gameport = gameport;
+	init_timer(&interact->timer);
+	interact->timer.data = (long) interact;
+	interact->timer.function = interact_timer;
 
 	gameport_set_drvdata(gameport, interact);
 
@@ -241,9 +252,6 @@
 		goto fail2;
 	}
 
-	gameport_set_poll_handler(gameport, interact_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	sprintf(interact->phys, "%s/input0", gameport->phys);
 
 	interact->type = i;
diff -u b/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
--- b/drivers/input/joystick/joydump.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/joydump.c	2005-02-28 17:20:10 -08:00
@@ -57,9 +57,9 @@
 	unsigned long flags;
 	unsigned char u;
 
-	printk(KERN_INFO "joydump: ,------------------ START ----------------.\n");
-	printk(KERN_INFO "joydump: | Dumping: %30s |\n", gameport->phys);
-	printk(KERN_INFO "joydump: | Speed: %28d kHz |\n", gameport->speed);
+	printk(KERN_INFO "joydump: ,------------------- START ------------------.\n");
+	printk(KERN_INFO "joydump: | Dumping gameport%s.\n", gameport->phys);
+	printk(KERN_INFO "joydump: | Speed: %4d kHz.                            |\n", gameport->speed);
 
 	if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) {
 
@@ -67,17 +67,17 @@
 
 		if (gameport_open(gameport, drv, GAMEPORT_MODE_COOKED)) {
 
-			printk(KERN_INFO "joydump: | Cooked not available either. Failing.   |\n");
-			printk(KERN_INFO "joydump: `------------------- END -----------------'\n");
+			printk(KERN_INFO "joydump: | Cooked not available either. Failing.      |\n");
+			printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
 			return -ENODEV;
 		}
 
 		gameport_cooked_read(gameport, axes, &buttons);
 
 		for (i = 0; i < 4; i++)
-			printk(KERN_INFO "joydump: | Axis %d: %4d.                           |\n", i, axes[i]);
-		printk(KERN_INFO "joydump: | Buttons %02x.                             |\n", buttons);
-		printk(KERN_INFO "joydump: `------------------- END -----------------'\n");
+			printk(KERN_INFO "joydump: | Axis %d: %4d.                              |\n", i, axes[i]);
+		printk(KERN_INFO "joydump: | Buttons %02x.                                |\n", buttons);
+		printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
 	}
 
 	timeout = gameport_time(gameport, 10000); /* 10 ms */
@@ -124,8 +124,8 @@
 	dump = buf;
 	prev = dump;
 
-	printk(KERN_INFO "joydump: >------------------ DATA -----------------<\n");
-	printk(KERN_INFO "joydump: | index: %3d delta: %3d us data: ", 0, 0);
+	printk(KERN_INFO "joydump: >------------------- DATA -------------------<\n");
+	printk(KERN_INFO "joydump: | index: %3d delta: %3d.%02d us data: ", 0, 0, 0);
 	for (j = 7; j >= 0; j--)
 		printk("%d", (dump->data >> j) & 1);
 	printk(" |\n");
@@ -136,12 +136,12 @@
 			i, dump->time - prev->time);
 		for (j = 7; j >= 0; j--)
 			printk("%d", (dump->data >> j) & 1);
-		printk(" |\n");
+		printk("    |\n");
 	}
 	kfree(buf);
 
 jd_end:
-	printk(KERN_INFO "joydump: `------------------- END -----------------'\n");
+	printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
 
 	return 0;
 }
diff -u b/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
--- b/drivers/input/joystick/sidewinder.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/joystick/sidewinder.c	2005-02-28 17:20:10 -08:00
@@ -1,5 +1,7 @@
 /*
- *  Copyright (c) 1998-2005 Vojtech Pavlik
+ * $Id: sidewinder.c,v 1.29 2002/01/22 20:28:51 vojtech Exp $
+ *
+ *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
 /*
@@ -45,18 +47,18 @@
  * as well as break everything.
  */
 
-#undef SW_DEBUG
-#undef SW_DEBUG_DATA
+/* #define SW_DEBUG */
 
-#define SW_START	600	/* The time we wait for the first bit [600 us] */
-#define SW_STROBE	60	/* Max time per bit [60 us] */
-#define SW_TIMEOUT	6	/* Wait for everything to settle [6 ms] */
+#define SW_START	400	/* The time we wait for the first bit [400 us] */
+#define SW_STROBE	45	/* Max time per bit [45 us] */
+#define SW_TIMEOUT	4000	/* Wait for everything to settle [4 ms] */
 #define SW_KICK		45	/* Wait after A0 fall till kick [45 us] */
 #define SW_END		8	/* Number of bits before end of packet to kick */
 #define SW_FAIL		16	/* Number of packet read errors to fail and reinitialize */
 #define SW_BAD		2	/* Number of packet read errors to switch off 3d Pro optimization */
 #define SW_OK		64	/* Number of packet read successes to switch optimization back on */
 #define SW_LENGTH	512	/* Max number of bits in a packet */
+#define SW_REFRESH	HZ/50	/* Time to wait between updates of joystick data [20 ms] */
 
 #ifdef SW_DEBUG
 #define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg)
@@ -113,6 +115,7 @@
 
 struct sw {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[4];
 	char name[64];
 	char phys[4][32];
@@ -124,6 +127,7 @@
 	int ok;
 	int reads;
 	int bads;
+	int used;
 };
 
 /*
@@ -139,7 +143,7 @@
 	unsigned char pending, u, v;
 
 	i = -id;						/* Don't care about data, only want ID */
-	timeout = id ? gameport_time(gameport, SW_TIMEOUT * 1000) : 0; /* Set up global timeout for ID packet */
+	timeout = id ? gameport_time(gameport, SW_TIMEOUT) : 0;	/* Set up global timeout for ID packet */
 	kick = id ? gameport_time(gameport, SW_KICK) : 0;	/* Set up kick timeout for ID packet */
 	start = gameport_time(gameport, SW_START);
 	strobe = gameport_time(gameport, SW_STROBE);
@@ -193,7 +197,7 @@
 
 	local_irq_restore(flags);					/* Done - relax */
 
-#ifdef SW_DEBUG_DATA
+#ifdef SW_DEBUG
 	{
 		int j;
 		printk(KERN_DEBUG "sidewinder.c: Read %d triplets. [", i);
@@ -248,7 +252,7 @@
 	i = 0;
         do {
                 gameport_trigger(gameport);			/* Trigger */
-		t = gameport_time(gameport, SW_TIMEOUT * 1000);
+		t = gameport_time(gameport, SW_TIMEOUT);
 		while ((gameport_read(gameport) & 1) && t) t--;	/* Wait for axis to fall back to 0 */
                 udelay(seq[i]);					/* Delay magic time */
         } while (seq[++i]);
@@ -478,13 +482,13 @@
 		" - reinitializing joystick.\n", sw->gameport->phys);
 
 	if (!i && sw->type == SW_ID_3DP) {					/* 3D Pro can be in analog mode */
-		mdelay(3 * SW_TIMEOUT);
+		udelay(3 * SW_TIMEOUT);
 		sw_init_digital(sw->gameport);
 	}
 
-	mdelay(SW_TIMEOUT);
+	udelay(SW_TIMEOUT);
 	i = sw_read_packet(sw->gameport, buf, SW_LENGTH, 0);			/* Read normal data packet */
-	mdelay(SW_TIMEOUT);
+	udelay(SW_TIMEOUT);
 	sw_read_packet(sw->gameport, buf, SW_LENGTH, i);			/* Read ID packet, this initializes the stick */
 
 	sw->fail = SW_FAIL;
@@ -492,20 +496,22 @@
 	return -1;
 }
 
-static void sw_poll(struct gameport *gameport)
+static void sw_timer(unsigned long private)
 {
-	struct sw *sw = gameport_get_drvdata(gameport);
+	struct sw *sw = (void *) private;
 
 	sw->reads++;
 	if (sw_read(sw))
 		sw->bads++;
+	mod_timer(&sw->timer, jiffies + SW_REFRESH);
 }
 
 static int sw_open(struct input_dev *dev)
 {
 	struct sw *sw = dev->private;
 
-	gameport_start_polling(sw->gameport);
+	if (!sw->used++)
+		mod_timer(&sw->timer, jiffies + SW_REFRESH);
 	return 0;
 }
 
@@ -513,7 +519,8 @@
 {
 	struct sw *sw = dev->private;
 
-	gameport_stop_polling(sw->gameport);
+	if (!--sw->used)
+		del_timer(&sw->timer);
 }
 
 /*
@@ -599,6 +606,9 @@
 	}
 
 	sw->gameport = gameport;
+	init_timer(&sw->timer);
+	sw->timer.data = (long) sw;
+	sw->timer.function = sw_timer;
 
 	gameport_set_drvdata(gameport, sw);
 
@@ -610,14 +620,14 @@
 		gameport->phys, gameport->io, gameport->speed);
 
 	i = sw_read_packet(gameport, buf, SW_LENGTH, 0);		/* Read normal packet */
-	msleep(SW_TIMEOUT);
+	udelay(SW_TIMEOUT);
 	dbg("Init 1: Mode %d. Length %d.", m , i);
 
 	if (!i) {							/* No data. 3d Pro analog mode? */
 		sw_init_digital(gameport);				/* Switch to digital */
-		msleep(SW_TIMEOUT);
+		udelay(SW_TIMEOUT);
 		i = sw_read_packet(gameport, buf, SW_LENGTH, 0);	/* Retry reading packet */
-		msleep(SW_TIMEOUT);
+		udelay(SW_TIMEOUT);
 		dbg("Init 1b: Length %d.", i);
 		if (!i) {						/* No data -> FAIL */
 			err = -ENODEV;
@@ -627,18 +637,17 @@
 
 	j = sw_read_packet(gameport, idbuf, SW_LENGTH, i);		/* Read ID. This initializes the stick */
 	m |= sw_guess_mode(idbuf, j);					/* ID packet should carry mode info [3DP] */
-	dbg("Init 2: Mode %d. ID Length %d.", m, j);
+	dbg("Init 2: Mode %d. ID Length %d.", m , j);
 
-	if (j <= 0) {							/* Read ID failed. Happens in 1-bit mode on PP */
-		msleep(SW_TIMEOUT);
+	if (!j) {							/* Read ID failed. Happens in 1-bit mode on PP */
+		udelay(SW_TIMEOUT);
 		i = sw_read_packet(gameport, buf, SW_LENGTH, 0);	/* Retry reading packet */
-		m |= sw_guess_mode(buf, i);
 		dbg("Init 2b: Mode %d. Length %d.", m, i);
 		if (!i) {
 			err = -ENODEV;
 			goto fail2;
 		}
-		msleep(SW_TIMEOUT);
+		udelay(SW_TIMEOUT);
 		j = sw_read_packet(gameport, idbuf, SW_LENGTH, i);	/* Retry reading ID */
 		dbg("Init 2c: ID Length %d.", j);
 	}
@@ -649,7 +658,7 @@
 
 	do {
 		k--;
-		msleep(SW_TIMEOUT);
+		udelay(SW_TIMEOUT);
 		i = sw_read_packet(gameport, buf, SW_LENGTH, 0);	/* Read data packet */
 		dbg("Init 3: Mode %d. Length %d. Last %d. Tries %d.", m, i, l, k);
 
@@ -717,9 +726,6 @@
 	sw_print_packet("Data", i * m, buf, m);
 #endif
 
-	gameport_set_poll_handler(gameport, sw_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	k = i;
 	l = j;
 
diff -u b/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
--- b/drivers/input/joystick/tmdc.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/joystick/tmdc.c	2005-02-28 17:20:09 -08:00
@@ -45,9 +45,10 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-#define TMDC_MAX_START		600	/* 600 us */
-#define TMDC_MAX_STROBE		60	/* 60 us */
+#define TMDC_MAX_START		400	/* 400 us */
+#define TMDC_MAX_STROBE		45	/* 45 us */
 #define TMDC_MAX_LENGTH		13
+#define TMDC_REFRESH_TIME	HZ/50	/* 20 ms */
 
 #define TMDC_MODE_M3DI		1
 #define TMDC_MODE_3DRP		3
@@ -93,6 +94,7 @@
 
 struct tmdc {
 	struct gameport *gameport;
+	struct timer_list timer;
 	struct input_dev dev[2];
 	char name[2][64];
 	char phys[2][32];
@@ -102,6 +104,7 @@
 	unsigned char absc[2];
 	unsigned char btnc[2][4];
 	unsigned char btno[2][4];
+	int used;
 	int reads;
 	int bads;
 	unsigned char exists;
@@ -157,13 +160,13 @@
 }
 
 /*
- * tmdc_poll() reads and analyzes ThrustMaster joystick data.
+ * tmdc_read() reads and analyzes ThrustMaster joystick data.
  */
 
-static void tmdc_poll(struct gameport *gameport)
+static void tmdc_timer(unsigned long private)
 {
 	unsigned char data[2][TMDC_MAX_LENGTH];
-	struct tmdc *tmdc = gameport_get_drvdata(gameport);
+	struct tmdc *tmdc = (void *) private;
 	struct input_dev *dev;
 	unsigned char r, bad = 0;
 	int i, j, k, l;
@@ -218,21 +221,23 @@
 	}
 
 	tmdc->bads += bad;
+
+	mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
 }
 
 static int tmdc_open(struct input_dev *dev)
 {
 	struct tmdc *tmdc = dev->private;
-
-	gameport_start_polling(tmdc->gameport);
+	if (!tmdc->used++)
+		mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
 	return 0;
 }
 
 static void tmdc_close(struct input_dev *dev)
 {
 	struct tmdc *tmdc = dev->private;
-
-	gameport_stop_polling(tmdc->gameport);
+	if (!--tmdc->used)
+		del_timer(&tmdc->timer);
 }
 
 /*
@@ -266,6 +271,9 @@
 		return -ENOMEM;
 
 	tmdc->gameport = gameport;
+	init_timer(&tmdc->timer);
+	tmdc->timer.data = (long) tmdc;
+	tmdc->timer.function = tmdc_timer;
 
 	gameport_set_drvdata(gameport, tmdc);
 
@@ -279,7 +287,4 @@
 	}
 
-	gameport_set_poll_handler(gameport, tmdc_poll);
-	gameport_set_poll_interval(gameport, 20);
-
 	for (j = 0; j < 2; j++)
 		if (tmdc->exists & (1 << j)) {
diff -u b/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- b/drivers/input/keyboard/atkbd.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/keyboard/atkbd.c	2005-02-28 17:20:10 -08:00
@@ -54,7 +54,7 @@
 module_param_named(softraw, atkbd_softraw, bool, 0);
 MODULE_PARM_DESC(softraw, "Use software generated rawmode");
 
-static int atkbd_scroll = 1;
+static int atkbd_scroll;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
 
@@ -143,6 +143,7 @@
 #define ATKBD_CMD_EX_SETLEDS	0x20eb
 #define ATKBD_CMD_OK_GETID	0x02e8
 
+
 #define ATKBD_RET_ACK		0xfa
 #define ATKBD_RET_NAK		0xfe
 #define ATKBD_RET_BAT		0xaa
@@ -161,22 +162,15 @@
 #define ATKBD_SCR_4		252
 #define ATKBD_SCR_8		251
 #define ATKBD_SCR_CLICK		250
-#define ATKBD_SCR_LEFT		249
-#define ATKBD_SCR_RIGHT		248
 
-#define ATKBD_SPECIAL		248
+#define ATKBD_SPECIAL		250
 
-static struct {
-	unsigned char keycode;
-	unsigned char set2;
-} atkbd_scroll_keys[] = {
-	{ ATKBD_SCR_1,     0xc5 },
-	{ ATKBD_SCR_2,     0xa9 },
-	{ ATKBD_SCR_4,     0xb6 },
-	{ ATKBD_SCR_8,     0xa7 },
-	{ ATKBD_SCR_CLICK, 0xe0 },
-	{ ATKBD_SCR_LEFT,  0xcb },
-	{ ATKBD_SCR_RIGHT, 0xd2 },
+static unsigned char atkbd_scroll_keys[5][2] = {
+	{ ATKBD_SCR_1,     0x45 },
+	{ ATKBD_SCR_2,     0x29 },
+	{ ATKBD_SCR_4,     0x36 },
+	{ ATKBD_SCR_8,     0x27 },
+	{ ATKBD_SCR_CLICK, 0x60 },
 };
 
 /*
@@ -259,7 +253,7 @@
 {
 	struct atkbd *atkbd = serio_get_drvdata(serio);
 	unsigned int code = data;
-	int scroll = 0, hscroll = 0, click = -1;
+	int scroll = 0, click = -1;
 	int value;
 
 #ifdef ATKBD_DEBUG
@@ -378,12 +372,6 @@
 		case ATKBD_SCR_CLICK:
 			click = !atkbd->release;
 			break;
-		case ATKBD_SCR_LEFT:
-			hscroll = -1;
-			break;
-		case ATKBD_SCR_RIGHT:
-			hscroll = 1;
-			break;
 		default:
 			value = atkbd->release ? 0 :
 				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
@@ -405,12 +393,10 @@
 			atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
 	}
 
-	if (atkbd->scroll) {
+	if (scroll || click != -1) {
 		input_regs(&atkbd->dev, regs);
-		if (click != -1)
-			input_report_key(&atkbd->dev, BTN_MIDDLE, click);
+		input_report_key(&atkbd->dev, BTN_MIDDLE, click);
 		input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
-		input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll);
 		input_sync(&atkbd->dev);
 	}
 
@@ -419,6 +405,7 @@
 	return IRQ_HANDLED;
 }
 
+
 /*
  * Event callback from the input module. Events that change the state of
  * the hardware are processed here.
@@ -710,9 +697,12 @@
 			atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
 			atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
 			if (atkbd->scroll)
-				for (j = 0; j < ARRAY_SIZE(atkbd_scroll_keys); j++)
-					if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j].set2)
-						atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j].keycode;
+				for (j = 0; i < 5; i++) {
+					if (atkbd_unxlate_table[i] == atkbd_scroll_keys[j][1])
+						atkbd->keycode[i] = atkbd_scroll_keys[j][0];
+					if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j][1])
+						atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j][0];
+				}
 		}
 	} else if (atkbd->set == 3) {
 		memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
@@ -720,8 +710,8 @@
 		memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
 
 		if (atkbd->scroll)
-			for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++)
-				atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode;
+			for (i = 0; i < 5; i++)
+				atkbd->keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0];
 	}
 }
 
@@ -767,7 +757,7 @@
 
 	if (atkbd->scroll) {
 		atkbd->dev.evbit[0] |= BIT(EV_REL);
-		atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+		atkbd->dev.relbit[0] = BIT(REL_WHEEL);
 		set_bit(BTN_MIDDLE, atkbd->dev.keybit);
 	}
 
diff -u b/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- b/drivers/input/misc/uinput.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/misc/uinput.c	2005-02-28 17:20:10 -08:00
@@ -222,11 +222,12 @@
 	unsigned int cnt;
 	int retval = 0;
 
-	for (cnt = 0; cnt < ABS_MAX + 1; cnt++) {
+	for (cnt = 0; cnt < ABS_MAX; cnt++) {
 		if (!test_bit(cnt, dev->absbit))
 			continue;
 
-		if ((dev->absmax[cnt] <= dev->absmin[cnt])) {
+		if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
+		    (dev->absmax[cnt] <= dev->absmin[cnt])) {
 			printk(KERN_DEBUG
 				"%s: invalid abs[%02x] min:%d max:%d\n",
 				UINPUT_NAME, cnt,
@@ -235,7 +236,8 @@
 			break;
 		}
 
-		if (dev->absflat[cnt] > (dev->absmax[cnt] - dev->absmin[cnt])) {
+		if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
+		    (dev->absflat[cnt] > dev->absmax[cnt])) {
 			printk(KERN_DEBUG
 				"%s: absflat[%02x] out of range: %d "
 				"(min:%d/max:%d)\n",
diff -u b/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
--- b/drivers/input/mouse/alps.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/mouse/alps.c	2005-02-28 17:20:09 -08:00
@@ -4,7 +4,6 @@
  * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
  * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
- * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
  *
  * ALPS detection, tap switching and status querying info is taken from
  * tpconfig utility (by C. Scott Ananian and Bruce Kall).
@@ -28,50 +27,53 @@
 #define dbg(format, arg...) do {} while (0)
 #endif
 
-#define ALPS_DUALPOINT	0x01
-#define ALPS_WHEEL	0x02
-#define ALPS_FW_BK	0x04
-#define ALPS_4BTN	0x08
-#define ALPS_OLDPROTO	0x10
-#define ALPS_PASS	0x20
-
-static struct alps_model_info alps_model_data[] = {
-	{ { 0x33, 0x02, 0x0a },	0x88, 0xf8, ALPS_OLDPROTO },
-	{ { 0x53, 0x02, 0x0a },	0xf8, 0xf8, 0 },
-	{ { 0x53, 0x02, 0x14 },	0xf8, 0xf8, 0 },
-	{ { 0x63, 0x02, 0x0a },	0xf8, 0xf8, 0 },
-	{ { 0x63, 0x02, 0x14 },	0xf8, 0xf8, 0 },
-	{ { 0x63, 0x02, 0x28 },	0xf8, 0xf8, 0 },
-	{ { 0x63, 0x02, 0x3c },	0x8f, 0x8f, ALPS_WHEEL },
-	{ { 0x63, 0x02, 0x50 },	0xef, 0xef, ALPS_FW_BK },
-	{ { 0x63, 0x02, 0x64 },	0xf8, 0xf8, 0 },
-	{ { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS },
-	{ { 0x73, 0x02, 0x0a },	0xf8, 0xf8, 0 },
-	{ { 0x73, 0x02, 0x14 },	0xf8, 0xf8, 0 },
-	{ { 0x20, 0x02, 0x0e },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
-	{ { 0x22, 0x02, 0x0a },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
-	{ { 0x22, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
-};
+#define ALPS_MODEL_GLIDEPOINT	1
+#define ALPS_MODEL_DUALPOINT	2
 
-/*
- * XXX - this entry is suspicious. First byte has zero lower nibble,
- * which is what a normal mouse would report. Also, the value 0x0e
- * isn't valid per PS/2 spec.
- */
+static struct alps_model_info {
+	unsigned char signature[3];
+	unsigned char model;
+} alps_model_data[] = {
+/*	{ { 0x33, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },	*/
+	{ { 0x53, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x53, 0x02, 0x14 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x63, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x63, 0x02, 0x14 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x73, 0x02, 0x0a },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x73, 0x02, 0x14 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x63, 0x02, 0x28 },	ALPS_MODEL_GLIDEPOINT },
+/*	{ { 0x63, 0x02, 0x3c },	ALPS_MODEL_GLIDEPOINT },	*/
+/*	{ { 0x63, 0x02, 0x50 },	ALPS_MODEL_GLIDEPOINT },	*/
+	{ { 0x63, 0x02, 0x64 },	ALPS_MODEL_GLIDEPOINT },
+	{ { 0x20, 0x02, 0x0e },	ALPS_MODEL_DUALPOINT },
+	{ { 0x22, 0x02, 0x0a },	ALPS_MODEL_DUALPOINT },
+	{ { 0x22, 0x02, 0x14 }, ALPS_MODEL_DUALPOINT },
+	{ { 0x63, 0x03, 0xc8 },	ALPS_MODEL_DUALPOINT },
+};
 
 /*
- * ALPS abolute Mode - new format
- * 
- * byte 0:  1    ?    ?    ?    1    ?    ?    ? 
+ * ALPS abolute Mode
+ * byte 0:  1    1    1    1    1  mid0 rig0 lef0
  * byte 1:  0   x6   x5   x4   x3   x2   x1   x0
- * byte 2:  0   x10  x9   x8   x7    ?  fin  ges
- * byte 3:  0   y9   y8   y7    1    M    R    L 
+ * byte 2:  0   x10  x9   x8   x7  up1  fin  ges
+ * byte 3:  0   y9   y8   y7    1  mid1 rig1 lef1
  * byte 4:  0   y6   y5   y4   y3   y2   y1   y0
  * byte 5:  0   z6   z5   z4   z3   z2   z1   z0
  *
- * ?'s can have different meanings on different models,
- * such as wheel rotation, extra buttons, stick buttons
- * on a dualpoint, etc.
+ * On a dualpoint, {mid,rig,lef}0 are the stick, 1 are the pad.
+ * We just 'or' them together for now.
+ *
+ * We used to send 'ges'tures as BTN_TOUCH but this made it impossible
+ * to disable tap events in the synaptics driver since the driver
+ * was unable to distinguish a gesture tap from an actual button click.
+ * A tap gesture now creates an emulated touch that the synaptics
+ * driver can interpret as a tap event, if MaxTapTime=0 and
+ * MaxTapMove=0 then the driver will ignore taps.
+ *
+ * The touchpad on an 'Acer Aspire' has 4 buttons:
+ *   left,right,up,down.
+ * This device always sets {mid,rig,lef}0 to 1 and
+ * reflects left,right,down,up in lef1,rig1,mid1,up1.
  */
 
 static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
@@ -79,60 +81,57 @@
 	struct alps_data *priv = psmouse->private;
 	unsigned char *packet = psmouse->packet;
 	struct input_dev *dev = &psmouse->dev;
-	struct input_dev *dev2 = &priv->dev2;
-	int x, y, z, ges, fin, left, right, middle;
+	int x, y, z;
+	int left = 0, right = 0, middle = 0;
+	int ges, fin;
 
 	input_regs(dev, regs);
 
 	if ((packet[0] & 0xc8) == 0x08) {   /* 3-byte PS/2 packet */
-		input_report_key(dev2, BTN_LEFT,   packet[0] & 1);    
-		input_report_key(dev2, BTN_RIGHT,  packet[0] & 2);
-		input_report_key(dev2, BTN_MIDDLE, packet[0] & 4);
-		input_report_rel(dev2, REL_X, packet[1] ?
-			(int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
-		input_report_rel(dev2, REL_Y, packet[2] ?
-			(int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
-		input_sync(dev2);
+		x = packet[1];
+		if (packet[0] & 0x10)
+			x = x - 256;
+		y = packet[2];
+		if (packet[0] & 0x20)
+			y = y - 256;
+		left  = (packet[0]     ) & 1;
+		right = (packet[0] >> 1) & 1;
+
+		input_report_rel(dev, REL_X, x);
+		input_report_rel(dev, REL_Y, -y);
+		input_report_key(dev, BTN_A, left);
+		input_report_key(dev, BTN_B, right);
+		input_sync(dev);
 		return;
 	}
 
-	if (priv->i->flags & ALPS_OLDPROTO) {
-		left = packet[2] & 0x08;
-		right = packet[2] & 0x10;
-		middle = 0;
-		x = (packet[1] & 0x7f) | ((packet[0] & 0x07) << 7);
-		y = (packet[4] & 0x7f) | ((packet[3] & 0x07) << 7);
-		z = packet[5];
-	} else {
-		left = packet[3] & 1;
-		right = packet[3] & 2;
-		middle = packet[3] & 4;
-		x = (packet[1] & 0x7f) | ((packet[2] & 0x78) << (7 - 3));
-		y = (packet[4] & 0x7f) | ((packet[3] & 0x70) << (7 - 4));
-		z = packet[5];
-	}
-
-	ges = packet[2] & 1;
-	fin = packet[2] & 2;
-
-	/* Dualpoint has stick buttons in byte 0 */
-	if (priv->i->flags & ALPS_DUALPOINT) {
-	
-		input_report_key(dev2, BTN_LEFT,    packet[0]       & 1);    
-		input_report_key(dev2, BTN_MIDDLE, (packet[0] >> 2) & 1);
-		input_report_key(dev2, BTN_RIGHT,  (packet[0] >> 1) & 1);
-
-		/* Relative movement packet */
- 		if (z == 127) {
-			input_report_rel(dev2, REL_X,  (x > 383 ? x : (x - 768)));
-			input_report_rel(dev2, REL_Y, -(y > 255 ? y : (x - 512)));
-			input_sync(dev2);
-			return;
-		}
+	x = (packet[1] & 0x7f) | ((packet[2] & 0x78)<<(7-3));
+	y = (packet[4] & 0x7f) | ((packet[3] & 0x70)<<(7-4));
+	z = packet[5];
+
+	if ((priv->model == ALPS_MODEL_DUALPOINT) && (z == 127)) {
+		/* DualPoint stick, relative packet */
+		if (x > 383)
+			x = x - 768;
+		if (y > 255)
+			y = y - 512;
+		left  = packet[3] & 1;
+		right = (packet[3] >> 1) & 1;
+
+		input_report_rel(dev, REL_X, x);
+		input_report_rel(dev, REL_Y, -y);
+		input_report_key(dev, BTN_LEFT, left);
+		input_report_key(dev, BTN_RIGHT, right);
+		input_sync(dev);
+		return;
 	}
 
+	ges = packet[2] & 1;		    /* gesture bit */
+	fin = packet[2] & 2;		    /* finger bit */
+
 	/* Convert hardware tap to a reasonable Z value */
-	if (ges && !fin) z = 40;
+	if (ges && !fin)
+		z = 40;
 
 	/*
 	 * A "tap and drag" operation is reported by the hardware as a transition
@@ -155,29 +154,37 @@
 		input_report_abs(dev, ABS_X, x);
 		input_report_abs(dev, ABS_Y, y);
 	}
-
 	input_report_abs(dev, ABS_PRESSURE, z);
 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
 
+	left  |= (packet[3]     ) & 1;
+	right |= (packet[3] >> 1) & 1;
+	if (packet[0] == 0xff) {
+		int back    = (packet[3] >> 2) & 1;
+		int forward = (packet[2] >> 2) & 1;
+		if (back && forward) {
+			middle = 1;
+			back = 0;
+			forward = 0;
+		}
+		input_report_key(dev, BTN_BACK,    back);
+		input_report_key(dev, BTN_FORWARD, forward);
+	} else {
+		left   |= (packet[0]     ) & 1;
+		right  |= (packet[0] >> 1) & 1;
+		middle |= (packet[0] >> 2) & 1;
+		middle |= (packet[3] >> 2) & 1;
+	}
+
 	input_report_key(dev, BTN_LEFT, left);
 	input_report_key(dev, BTN_RIGHT, right);
 	input_report_key(dev, BTN_MIDDLE, middle);
 
-	if (priv->i->flags & ALPS_WHEEL)
-		input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08));
-
-	if (priv->i->flags & ALPS_FW_BK) {
-		input_report_key(dev, BTN_FORWARD, packet[0] & 0x10);
-		input_report_key(dev, BTN_BACK, packet[2] & 0x04);
-	}
-
 	input_sync(dev);
 }
 
 static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
-	struct alps_data *priv = psmouse->private;
-
 	if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
 		if (psmouse->pktcnt == 3) {
 			alps_process_packet(psmouse, regs);
@@ -186,12 +193,15 @@
 		return PSMOUSE_GOOD_DATA;
 	}
 
-	if ((psmouse->packet[0] & priv->i->mask0) != priv->i->byte0)
+	/* ALPS absolute mode packets start with 0b11111mrl */
+	if ((psmouse->packet[0] & 0xf8) != 0xf8)
 		return PSMOUSE_BAD_DATA;
 
 	/* Bytes 2 - 6 should have 0 in the highest bit */
+	if (psmouse->pktcnt > 1 && psmouse->pktcnt <= 6 &&
+	    (psmouse->packet[psmouse->pktcnt] & 0x80))
 	if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
-	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80))
+	    (psmouse->packet[psmouse->pktcnt-1] & 0x80))
 		return PSMOUSE_BAD_DATA;
 
 	if (psmouse->pktcnt == 6) {
@@ -202,58 +212,51 @@
 	return PSMOUSE_GOOD_DATA;
 }
 
-static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
+static int alps_get_model(struct psmouse *psmouse)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
 	unsigned char param[4];
 	int i;
 
 	/*
 	 * First try "E6 report".
-	 * ALPS should return 0,0,10 or 0,0,100
+	 * ALPS should return 0x00,0x00,0x0a or 0x00,0x00,0x64
 	 */
 	param[0] = 0;
 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
 	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
 	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
 	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11))
-		return NULL;
+		return -1;
 
 	param[0] = param[1] = param[2] = 0xff;
 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
-		return NULL;
+		return -1;
 
 	dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
 
-	if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100))
-		return NULL;
+	if (param[0] != 0x00 || param[1] != 0x00 || (param[2] != 0x0a && param[2] != 0x64))
+		return -1;
 
-	/*
-	 * Now try "E7 report". Allowed responses are in
-	 * alps_model_data[].signature
-	 */
+	/* Now try "E7 report". ALPS should return 0x33 in byte 1 */
 	param[0] = 0;
 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
 	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
 	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
 	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21))
-		return NULL;
+		return -1;
 
 	param[0] = param[1] = param[2] = 0xff;
 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
-		return NULL;
+		return -1;
 
 	dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
 
-	for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++);
-	*version = (param[0] << 8) | (param[1] << 4) | i;
-
 	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
 		if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
-			return alps_model_data + i;
+			return alps_model_data[i].model;
 
-	return NULL;
+	return -1;
 }
 
 /*
@@ -346,12 +349,11 @@
 {
 	struct alps_data *priv = psmouse->private;
 	unsigned char param[4];
-	int version;
 
-	if ((priv->i = alps_get_model(psmouse, &version)) < 0)
+	if ((priv->model = alps_get_model(psmouse)) < 0)
 		return -1;
 
-	if (priv->i->flags & ALPS_PASS && alps_passthrough_mode(psmouse, 1))
+	if (priv->model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1))
 		return -1;
 
 	if (alps_get_status(psmouse, param))
@@ -365,7 +367,7 @@
 		return -1;
 	}
 
-	if (priv->i->flags == ALPS_PASS && alps_passthrough_mode(psmouse, 0))
+	if (priv->model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 0))
 		return -1;
 
 	return 0;
@@ -373,27 +375,27 @@
 
 static void alps_disconnect(struct psmouse *psmouse)
 {
-	struct alps_data *priv = psmouse->private;
 	psmouse_reset(psmouse);
-	input_unregister_device(&priv->dev2);
-	kfree(priv);
+	kfree(psmouse->private);
 }
 
 int alps_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv;
 	unsigned char param[4];
-	int version;
 
 	psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
 	if (!priv)
 		goto init_fail;
 	memset(priv, 0, sizeof(struct alps_data));
 
-	if ((priv->i = alps_get_model(psmouse, &version)) < 0)
+	if ((priv->model = alps_get_model(psmouse)) < 0)
 		goto init_fail;
 
-	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
+	printk(KERN_INFO "ALPS Touchpad (%s) detected\n",
+		priv->model == ALPS_MODEL_GLIDEPOINT ? "Glidepoint" : "Dualpoint");
+
+	if (priv->model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1))
 		goto init_fail;
 
 	if (alps_get_status(psmouse, param)) {
@@ -412,44 +414,24 @@
 		goto init_fail;
 	}
 
-	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+	if (priv->model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 0))
 		goto init_fail;
 
-	psmouse->dev.evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
-	psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
-	psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
-	psmouse->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
+	psmouse->dev.relbit[LONG(REL_X)] |= BIT(REL_X);
+	psmouse->dev.relbit[LONG(REL_Y)] |= BIT(REL_Y);
+	psmouse->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A);
+	psmouse->dev.keybit[LONG(BTN_B)] |= BIT(BTN_B);
 
 	psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
 	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0);
 	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 767, 0, 0);
 	input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
 
-	if (priv->i->flags & ALPS_WHEEL) {
-		psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
-		psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
-	}
-
-	if (priv->i->flags & ALPS_FW_BK) {
-		psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
-		psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
-	}
-
-	sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys);
-	priv->dev2.phys = priv->phys;
-	priv->dev2.name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
-	priv->dev2.id.bustype = BUS_I8042;
-	priv->dev2.id.vendor = 0x0002;
-	priv->dev2.id.product = PSMOUSE_ALPS;
-	priv->dev2.id.version = 0x0000; 
-	
-	priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
-	priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-
-	input_register_device(&priv->dev2);
-
-	printk(KERN_INFO "input: %s on %s\n", priv->dev2.name, psmouse->ps2dev.serio->phys);
+	psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
+	psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
+	psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
+	psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
 
 	psmouse->protocol_handler = alps_process_byte;
 	psmouse->disconnect = alps_disconnect;
@@ -465,19 +447,12 @@
 
 int alps_detect(struct psmouse *psmouse, int set_properties)
 {
-	int version;
-	struct alps_model_info *model; 
-
-	if (!(model = alps_get_model(psmouse, &version)))
+	if (alps_get_model(psmouse) < 0)
 		return -1;
 
 	if (set_properties) {
 		psmouse->vendor = "ALPS";
-		if (model->flags & ALPS_DUALPOINT) 
-			psmouse->name = "DualPoint TouchPad";
-		else
-			psmouse->name = "GlidePoint";
-		psmouse->model = version;
+		psmouse->name = "TouchPad";
 	}
 	return 0;
 }
diff -u b/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
--- b/drivers/input/mouse/alps.h	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/mouse/alps.h	2005-02-28 17:20:10 -08:00
@@ -2,7 +2,6 @@
  * ALPS touchpad PS/2 mouse driver
  *
  * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
- * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published by
@@ -15,18 +14,9 @@
 int alps_detect(struct psmouse *psmouse, int set_properties);
 int alps_init(struct psmouse *psmouse);
 
-struct alps_model_info {
-        unsigned char signature[3];
-        unsigned char byte0, mask0;
-        unsigned char flags;
-};
-
 struct alps_data {
-	struct input_dev dev2;		/* Relative device */
-	char name[32];			/* Name */
-	char phys[32];			/* Phys */
-	struct alps_model_info *i; 	/* Info */
-	int prev_fin;			/* Finger bit from previous packet */
+	int model;			    /* Glidepoint or Dualpoint */
+	int prev_fin;			    /* Finger bit from previous packet */
 };
 
 #endif
diff -u b/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- b/drivers/input/mouse/psmouse-base.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/mouse/psmouse-base.c	2005-02-28 17:20:09 -08:00
@@ -423,7 +423,7 @@
  * upsets the thinkingmouse).
  */
 
-	if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0)
+	if (max_proto > PSMOUSE_PS2 && thinking_detect(psmouse, set_properties) == 0)
 		return PSMOUSE_THINKPS;
 
 /*
reverted:
--- b/drivers/input/mouse/psmouse.h	2005-02-28 17:23:09 -08:00
+++ a/drivers/input/mouse/psmouse.h	2005-02-28 17:23:09 -08:00
@@ -44,7 +44,7 @@
 	unsigned char pktcnt;
 	unsigned char pktsize;
 	unsigned char type;
+	unsigned char model;
-	unsigned int model;
 	unsigned long last;
 	unsigned long out_of_sync;
 	enum psmouse_state state;
diff -u b/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- b/drivers/input/mouse/sermouse.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/mouse/sermouse.c	2005-02-28 17:20:09 -08:00
@@ -283,7 +283,7 @@
 	serio_set_drvdata(serio, sermouse);
 
 	err = serio_open(serio, drv);
-	if (err) {
+	if (serio_open(serio, drv)) {
 		serio_set_drvdata(serio, NULL);
 		kfree(sermouse);
 		return err;
reverted:
--- b/drivers/input/power.c	2005-02-28 17:23:09 -08:00
+++ a/drivers/input/power.c	2005-02-28 17:23:09 -08:00
@@ -58,6 +58,8 @@
 
 	printk("Entering power_event\n");
 
+	if (type != EV_KEY || type != EV_PWR) return;
+
 	if (type == EV_PWR) {
 		switch (code) {
 			case KEY_SUSPEND:
@@ -74,9 +76,7 @@
 			default:
 				return;
 		}
+	} else {
-	}
-
-	if (type == EV_KEY) {
 		switch (code) {
 			case KEY_SUSPEND:
 				printk("Powering down input device\n");
@@ -102,6 +102,12 @@
 					  struct input_device_id *id)
 {
 	struct input_handle *handle;
+
+	if (!test_bit(EV_KEY, dev->evbit) || !test_bit(EV_PWR, dev->evbit))
+		return NULL;
+
+	if (!test_bit(KEY_SUSPEND, dev->keybit) || (!test_bit(KEY_POWER, dev->keybit)))
+		return NULL;
 
 	if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
 		return NULL;
diff -u b/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
--- b/drivers/input/serio/i8042-x86ia64io.h	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/serio/i8042-x86ia64io.h	2005-02-28 17:20:10 -08:00
@@ -88,57 +88,50 @@
 };
 #endif
 
-
 #ifdef CONFIG_PNP
 #include <linux/pnp.h>
 
 static int i8042_pnp_kbd_registered;
 static int i8042_pnp_aux_registered;
 
-static int i8042_pnp_command_reg;
-static int i8042_pnp_data_reg;
-static int i8042_pnp_kbd_irq;
-static int i8042_pnp_aux_irq;
-
-static char i8042_pnp_kbd_name[32];
-static char i8042_pnp_aux_name[32];
 
 static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
 {
 	if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
-		i8042_pnp_data_reg = pnp_port_start(dev,0);
+		i8042_data_reg = pnp_port_start(dev,0);
+	else
+		printk(KERN_WARNING "PNP: [%s] has no data port; default is 0x%x\n",
+			pnp_dev_name(dev), i8042_data_reg);
 
 	if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
-		i8042_pnp_command_reg = pnp_port_start(dev, 1);
+		i8042_command_reg = pnp_port_start(dev,1);
+	else
+		printk(KERN_WARNING "PNP: [%s] has no command port; default is 0x%x\n",
+			pnp_dev_name(dev), i8042_command_reg);
 
 	if (pnp_irq_valid(dev,0))
-		i8042_pnp_kbd_irq = pnp_irq(dev, 0);
+		i8042_kbd_irq = pnp_irq(dev,0);
+	else
+		printk(KERN_WARNING "PNP: [%s] has no IRQ; default is %d\n",
+			pnp_dev_name(dev), i8042_kbd_irq);
+
+	printk(KERN_INFO "PNP: %s [%s,%s] at 0x%x,0x%x irq %d\n",
+		"PS/2 Keyboard Controller", did->id, pnp_dev_name(dev),
+		i8042_data_reg, i8042_command_reg, i8042_kbd_irq);
 
-	strncpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
-	if (strlen(pnp_dev_name(dev))) {
-		strncat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
-		strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
-	}
-	
 	return 0;
 }
 
 static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
 {
-	if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
-		i8042_pnp_data_reg = pnp_port_start(dev,0);
-
-	if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
-		i8042_pnp_command_reg = pnp_port_start(dev, 1);
+	if (pnp_irq_valid(dev,0))
+		i8042_aux_irq = pnp_irq(dev,0);
+	else
+		printk(KERN_WARNING "PNP: [%s] has no IRQ; default is %d\n",
+			pnp_dev_name(dev), i8042_aux_irq);
 
-	if (pnp_irq_valid(dev, 0))
-		i8042_pnp_aux_irq = pnp_irq(dev, 0);
-
-	strncpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
-	if (strlen(pnp_dev_name(dev))) {
-		strncat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
-		strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
-	}
+	printk(KERN_INFO "PNP: %s [%s,%s] irq %d\n",
+		"PS/2 Mouse Controller", did->id, pnp_dev_name(dev), i8042_aux_irq);
 
 	return 0;
 }
@@ -156,13 +149,7 @@
 };
 
 static struct pnp_device_id pnp_aux_devids[] = {
-	{ .id = "PNP0f03", .driver_data = 0 },
-	{ .id = "PNP0f0b", .driver_data = 0 },
-	{ .id = "PNP0f0e", .driver_data = 0 },
-	{ .id = "PNP0f12", .driver_data = 0 },
 	{ .id = "PNP0f13", .driver_data = 0 },
-	{ .id = "PNP0f19", .driver_data = 0 },
-	{ .id = "PNP0f1c", .driver_data = 0 },
 	{ .id = "SYN0801", .driver_data = 0 },
 	{ .id = "", },
 };
@@ -173,81 +160,42 @@
 	.probe          = i8042_pnp_aux_probe,
 };
 
-static void i8042_pnp_exit(void)
-{
-	if (i8042_pnp_kbd_registered)
-		pnp_unregister_driver(&i8042_pnp_kbd_driver);
-
-	if (i8042_pnp_aux_registered)
-		pnp_unregister_driver(&i8042_pnp_aux_driver);
-}
-
 static int i8042_pnp_init(void)
 {
-	int result_kbd, result_aux;
+	int result;
 
 	if (i8042_nopnp) {
 		printk("i8042: PNP detection disabled\n");
 		return 0;
 	}
 
-	if ((result_kbd = pnp_register_driver(&i8042_pnp_kbd_driver)) >= 0)
-		i8042_pnp_kbd_registered = 1;
-	if ((result_aux = pnp_register_driver(&i8042_pnp_aux_driver)) >= 0)
-		i8042_pnp_aux_registered = 1;
+	result = pnp_register_driver(&i8042_pnp_kbd_driver);
+	if (result < 0)
+		return result;
 
-	if (result_kbd <= 0 && result_aux <= 0) {
-		i8042_pnp_exit();
-#if defined(__ia64__)
+	if (result == 0) {
+		pnp_unregister_driver(&i8042_pnp_kbd_driver);
 		return -ENODEV;
-#else
-		printk(KERN_WARNING "PNP: No PS/2 controller found. Probing ports directly.\n");
-		return 0;
-#endif
-	}
-
-	if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
-	      i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) {
-		printk(KERN_WARNING "PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
-			i8042_pnp_data_reg, i8042_data_reg);
-		i8042_pnp_data_reg = i8042_data_reg;
-	}
-
-	if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
-	      i8042_pnp_command_reg != i8042_command_reg) || !i8042_pnp_data_reg) {
-		printk(KERN_WARNING "PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
-			i8042_pnp_command_reg, i8042_command_reg);
-		i8042_pnp_command_reg = i8042_command_reg;
-	}
-
-	if (!i8042_pnp_kbd_irq) {
-		printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %#x\n", i8042_kbd_irq);
-		i8042_pnp_kbd_irq = i8042_kbd_irq;
 	}
+	i8042_pnp_kbd_registered = 1;
 
-	if (result_aux > 0 && !i8042_pnp_aux_irq) {
-		printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq);
-		i8042_pnp_aux_irq = i8042_aux_irq;
-	}
-	
-#if defined(__ia64__)
-	if (result_aux <= 0)
+	result = pnp_register_driver(&i8042_pnp_aux_driver);
+	if (result >= 0)
+		i8042_pnp_aux_registered = 1;
+	if (result == 0)
 		i8042_noaux = 1;
-#endif
-
-	i8042_data_reg = i8042_pnp_data_reg;
-	i8042_command_reg = i8042_pnp_command_reg;
-	i8042_kbd_irq = i8042_pnp_kbd_irq;
-	i8042_aux_irq = i8042_pnp_aux_irq;
-
-	printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %d%s%d\n",
-		i8042_pnp_kbd_name, (result_kbd > 0 || result_aux > 0) ? "," : "", i8042_pnp_aux_name,
-		i8042_data_reg, i8042_command_reg, i8042_kbd_irq,
-		(result_aux > 0) ? "," : "", i8042_aux_irq);
 
 	return 0;
 }
 
+static void i8042_pnp_exit(void)
+{
+	if (i8042_pnp_kbd_registered)
+		pnp_unregister_driver(&i8042_pnp_kbd_driver);
+
+	if (i8042_pnp_aux_registered)
+		pnp_unregister_driver(&i8042_pnp_aux_driver);
+}
 #endif
 
 static inline int i8042_platform_init(void)
diff -u b/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- b/drivers/input/serio/parkbd.c	2005-02-28 17:23:08 -08:00
+++ b/drivers/input/serio/parkbd.c	2005-02-28 17:20:09 -08:00
@@ -16,23 +16,23 @@
  * 
  *  Parallel port            Keyboard port
  *
- *     +5V --------------------- +5V (4)
+ *     +5V --------------------- +5V
  *  
  *                 ______
  *     +5V -------|______|--.
  *                          |
- *     ACK (10) ------------|
- *                          |--- KBD CLOCK (5)
- *     STROBE (1) ---|<|----'
+ *     ACK -----------------|
+ *                          |--- KBD CLOCK
+ *     STROBE -------|<|----'
  *     
  *                 ______
  *     +5V -------|______|--.
  *                          |
- *     BUSY (11) -----------|
- *                          |--- KBD DATA (1)
- *     AUTOFD (14) --|<|----'
+ *     BUSY ----------------|
+ *                          |--- KBD DATA
+ *     AUTOFD -------|<|----'
  *
- *     GND (18-25) ------------- GND (3)
+ *     GND --------------------- GND
  *     
  * The diodes can be fairly any type, and the resistors should be somewhere
  * around 5 kOhm, but the adapter will likely work without the resistors,
diff -u b/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
--- b/drivers/input/touchscreen/elo.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/touchscreen/elo.c	2005-02-28 17:20:10 -08:00
@@ -80,7 +80,7 @@
 				input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
 				input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
 				input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
-				input_report_key(dev, BTN_TOUCH, elo->data[2] & 3);
+				input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
 				input_sync(dev);
 			}
 			elo->idx = 0;
@@ -129,7 +129,7 @@
 		case 5:
 			if ((data & 0xf0) == 0) {
 				input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
-				input_report_key(dev, BTN_TOUCH, elo->data[5]);
+				input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
 			}
 			input_sync(dev);
 			elo->idx = 0;
diff -u b/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
--- b/drivers/input/touchscreen/mk712.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/input/touchscreen/mk712.c	2005-02-28 17:20:10 -08:00
@@ -161,7 +161,7 @@
 
 static struct input_dev mk712_dev = {
 	.evbit   = { BIT(EV_KEY) | BIT(EV_ABS) },
-	.keybit  = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+	.keybit  = { [LONG(BTN_LEFT)] = BIT(BTN_TOUCH) },
 	.absbit  = { BIT(ABS_X) | BIT(ABS_Y) },
 	.open    = mk712_open,
 	.close   = mk712_close,
reverted:
--- b/drivers/usb/input/ati_remote.c	2005-02-28 17:23:09 -08:00
+++ a/drivers/usb/input/ati_remote.c	2005-02-28 17:23:09 -08:00
@@ -174,6 +174,7 @@
 	dma_addr_t outbuf_dma;
 
 	int open;                   /* open counter */
+	int present;                /* device plugged in? */
 	
 	unsigned char old_data[2];  /* Detect duplicate events */
 	unsigned long old_jiffies;
@@ -251,8 +252,8 @@
 	{KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_KPENTER, 1},    /* "check" */
 	{KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_MENU, 1},       /* "menu" */
 	{KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1},      /* Power */
+	{KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_PROG1, 1},      /* TV */
+	{KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_PROG2, 1},      /* DVD */
-	{KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_TV, 1},         /* TV */
-	{KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_DVD, 1},        /* DVD */
 	{KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1},        /* WEB */
 	{KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1},  /* "book" */
 	{KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_EDIT, 1},       /* "hand" */
@@ -262,14 +263,14 @@
 	{KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1},      /* right */
 	{KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1},       /* down */
 	{KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1},         /* up */
+	{KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_ENTER, 1},      /* "OK" */
-	{KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_OK, 1},         /* "OK" */
 	{KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_VOLUMEDOWN, 1}, /* VOL + */
 	{KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_VOLUMEUP, 1},   /* VOL - */
 	{KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_MUTE, 1},       /* MUTE  */
+	{KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELUP, 1},  /* CH + */
+	{KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */
-	{KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELUP, 1},  /* CH + */
-	{KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */
 	{KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_RECORD, 1},     /* ( o) red */
+	{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAYCD, 1},     /* ( >) */
-	{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1},       /* ( >) */
 	{KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1},     /* (<<) */
 	{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1},    /* (>>) */
 	{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1},       /* ([]) */ 
@@ -355,8 +356,19 @@
 {
 	struct ati_remote *ati_remote = inputdev->private;
 	
+	if (ati_remote == NULL) {
+		err("ati_remote: %s: object is NULL!\n", __FUNCTION__);
+		return;
+	}
+	
+	if (ati_remote->open <= 0)
+		dev_dbg(&ati_remote->interface->dev, "%s: Not open.\n", __FUNCTION__);
+	else
+		--ati_remote->open;
+	
+	/* If still present, disconnect will call delete. */
+	if (!ati_remote->present && !ati_remote->open)
+		ati_remote_delete(ati_remote);
-	if (!--ati_remote->open)
-		usb_kill_urb(ati_remote->irq_urb);
 }
 
 /*
@@ -800,6 +812,7 @@
 		 ati_remote->name, path);
 
 	usb_set_intfdata(interface, ati_remote);
+	ati_remote->present = 1;	
 	
 error:
 	if (buf)
@@ -827,7 +840,12 @@
 		return;
 	}
 	
+	/* Mark device as unplugged */
+	ati_remote->present = 0;
+
+	/* If device is still open, ati_remote_close will call delete. */
+	if (!ati_remote->open)
+		ati_remote_delete(ati_remote);
-	ati_remote_delete(ati_remote);
 
 	up(&disconnect_sem);
 }
diff -u b/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- b/drivers/usb/input/hid-core.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/usb/input/hid-core.c	2005-02-28 17:20:09 -08:00
@@ -227,14 +227,12 @@
 		return -1;
 	}
 
+	if (!(usages = max_t(int, parser->local.usage_index, parser->global.report_count)))
+		return 0; /* Ignore padding fields */
+
 	offset = report->size;
 	report->size += parser->global.report_size * parser->global.report_count;
 
-	if (!parser->local.usage_index) /* Ignore padding fields */
-		return 0; 
-
-	usages = max_t(int, parser->local.usage_index, parser->global.report_count);
-
 	if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL)
 		return 0;
 
@@ -814,7 +812,8 @@
 	__s32 max = field->logical_maximum;
 	__s32 *value;
 
-	if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC)))
+	value = kmalloc(sizeof(__s32)*count, GFP_ATOMIC);
+	if (!value)
 		return;
 
 	for (n = 0; n < count; n++) {
@@ -831,6 +830,14 @@
 	for (n = 0; n < count; n++) {
 
 		if (HID_MAIN_ITEM_VARIABLE & field->flags) {
+
+			if (field->flags & HID_MAIN_ITEM_RELATIVE) {
+				if (!value[n])
+					continue;
+			} else {
+				if (value[n] == field->value[n])
+					continue;
+			}
 			hid_process_event(hid, field, &field->usage[n], value[n], regs);
 			continue;
 		}
@@ -1000,21 +1007,63 @@
 	return 0;
 }
 
+int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
+{
+	struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT;
+	struct list_head *list = report_enum->report_list.next;
+	int i, j;
+
+	while (list != &report_enum->report_list) {
+		struct hid_report *report = (struct hid_report *) list;
+		list = list->next;
+		for (i = 0; i < report->maxfield; i++) {
+			*field = report->field[i];
+			for (j = 0; j < (*field)->maxusage; j++)
+				if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
+					return j;
+		}
+	}
+	return -1;
+}
+
 /*
- * Find a report field with a specified HID usage.
+ * Find a report with a specified HID usage.
  */
 
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
+int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type)
 {
-	struct hid_report *report;
-	int i;
+	struct hid_report_enum *report_enum = hid->report_enum + type;
+	struct list_head *list = report_enum->report_list.next;
+	int i, j;
+
+	while (list != &report_enum->report_list) {
+		*report = (struct hid_report *) list;
+		list = list->next;
+		for (i = 0; i < (*report)->maxfield; i++) {
+			struct hid_field *field = (*report)->field[i];
+			for (j = 0; j < field->maxusage; j++)
+				if (field->logical == wanted_usage)
+					return j;
+		}
+	}
+	return -1;
+}
+
+#if 0
+static int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field)
+{
+	int i, j;
 
-	list_for_each_entry(report, &hid->report_enum[type].report_list, list)
-		for (i = 0; i < report->maxfield; i++)
-			if (report->field[i]->logical == wanted_usage)
-				return report->field[i];
-	return NULL;
+	for (i = 0; i < report->maxfield; i++) {
+		*field = report->field[i];
+		for (j = 0; j < (*field)->maxusage; j++)
+			if ((*field)->usage[j].hid == wanted_usage)
+				return j;
+	}
+
+	return -1;
 }
+#endif
 
 static int hid_submit_out(struct hid_device *hid)
 {
@@ -1287,19 +1336,47 @@
 
 void hid_init_reports(struct hid_device *hid)
 {
+	struct hid_report_enum *report_enum;
 	struct hid_report *report;
-	int err, ret;
+	struct list_head *list;
+	int err, ret, size;
 
-	list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) {
-		int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered;
+	/*
+	 * The Set_Idle request is supposed to affect only the
+	 * "Interrupt In" pipe. Unfortunately, buggy devices such as
+	 * the BTC keyboard (ID 046e:5303) the request also affects
+	 * Get_Report requests on the control pipe.  In the worst
+	 * case, if the device was put on idle for an indefinite
+	 * amount of time (as we do below) and there are no input
+	 * events to report, the Get_Report requests will just hang
+	 * until we get a USB timeout.  To avoid this, we temporarily
+	 * establish a minimal idle time of 1ms.  This shouldn't hurt
+	 * bugfree devices and will cause a worst-case extra delay of
+	 * 1ms for buggy ones.
+	 */
+	usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+			HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (1 << 8),
+			hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+
+	report_enum = hid->report_enum + HID_INPUT_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
+		size = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
 		if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE;
 		if (size > hid->urbin->transfer_buffer_length)
 			hid->urbin->transfer_buffer_length = size;
 		hid_submit_report(hid, report, USB_DIR_IN);
+		list = list->next;
 	}
 
-	list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
+	report_enum = hid->report_enum + HID_FEATURE_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
 		hid_submit_report(hid, report, USB_DIR_IN);
+		list = list->next;
+	}
 
 	err = 0;
 	ret = hid_wait_io(hid);
@@ -1315,9 +1392,15 @@
 	if (err)
 		warn("timeout initializing reports\n");
 
-	usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
-		HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
-		hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+	report_enum = hid->report_enum + HID_INPUT_REPORT;
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
+		usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+			HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id,
+			hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+		list = list->next;
+	}
 }
 
 #define USB_VENDOR_ID_WACOM		0x056a
@@ -1422,9 +1505,6 @@
 #define USB_VENDOR_ID_CHICONY		0x04f2
 #define USB_DEVICE_ID_CHICONY_USBHUB_KB	0x0100
 
-#define USB_VENDOR_ID_BTC		0x046e
-#define USB_DEVICE_ID_BTC_KEYBOARD	0x5303
-
 
 /*
  * Alphabetically sorted blacklist by quirk type.
@@ -1502,7 +1582,6 @@
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
-	{ USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET},
 	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
 	{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
 
@@ -1746,7 +1825,7 @@
 	hid_free_device(hid);
 }
 
-static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct hid_device *hid;
 	char path[64];
reverted:
--- b/drivers/usb/input/hid-input.c	2005-02-28 17:23:08 -08:00
+++ a/drivers/usb/input/hid-input.c	2005-02-28 17:23:08 -08:00
@@ -404,6 +404,7 @@
 		return;
 
 	input_regs(input, regs);
+	input_event(input, EV_MSC, MSC_SCAN, usage->hid);
 
 	if (!usage->type)
 		return;
@@ -482,26 +483,10 @@
 	}
 }
 
-static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
-{
-	struct hid_report *report;
-	int i, j;
-
-	list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
-		for (i = 0; i < report->maxfield; i++) {
-			*field = report->field[i];
-			for (j = 0; j < (*field)->maxusage; j++)
-				if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
-					return j;
-		}
-	}
-	return -1;
-}
-
 static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct hid_device *hid = dev->private;
+	struct hid_field *field = NULL;
-	struct hid_field *field;
 	int offset;
 
 	if (type == EV_FF)
@@ -510,7 +495,7 @@
 	if (type != EV_LED)
 		return -1;
 
+	if ((offset = hid_find_field(hid, type, code, &field)) == -1) {
-	if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
 		warn("event field not found");
 		return -1;
 	}
@@ -542,7 +527,9 @@
 int hidinput_connect(struct hid_device *hid)
 {
 	struct usb_device *dev = hid->dev;
+	struct hid_report_enum *report_enum;
 	struct hid_report *report;
+	struct list_head *list;
 	struct hid_input *hidinput = NULL;
 	int i, j, k;
 
@@ -557,11 +544,16 @@
 	if (i == hid->maxcollection)
 		return -1;
 
+	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+		report_enum = hid->report_enum + k;
+		list = report_enum->report_list.next;
+		while (list != &report_enum->report_list) {
+			report = (struct hid_report *) list;
-	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++)
-		list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
 
+			if (!report->maxfield) {
+				list = list->next;
-			if (!report->maxfield)
 				continue;
+			}
 
 			if (!hidinput) {
 				hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
@@ -586,6 +578,9 @@
 				hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
 				hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
 				hidinput->input.dev = &hid->intf->dev;
+
+				set_bit(EV_MSC, hidinput->input.evbit);
+				set_bit(MSC_SCAN, hidinput->input.mscbit);
 			}
 
 			for (i = 0; i < report->maxfield; i++)
@@ -603,7 +598,10 @@
 				input_register_device(&hidinput->input);
 				hidinput = NULL;
 			}
+
+			list = list->next;
 		}
+	}
 
 	/* This only gets called when we are a single-input (most of the
 	 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
@@ -621,7 +619,7 @@
 	struct list_head *lh, *next;
 	struct hid_input *hidinput;
 
+	list_for_each_safe (lh, next, &hid->inputs) {
-	list_for_each_safe(lh, next, &hid->inputs) {
 		hidinput = list_entry(lh, struct hid_input, list);
 		input_unregister_device(&hidinput->input);
 		list_del(&hidinput->list);
reverted:
--- b/drivers/usb/input/hid.h	2005-02-28 17:23:08 -08:00
+++ a/drivers/usb/input/hid.h	2005-02-28 17:23:08 -08:00
@@ -484,10 +484,11 @@
 
 int hid_open(struct hid_device *);
 void hid_close(struct hid_device *);
+int hid_find_field(struct hid_device *, unsigned int, unsigned int, struct hid_field **);
 int hid_set_field(struct hid_field *, unsigned, __s32);
 void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
 void hid_init_reports(struct hid_device *hid);
+int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type);
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type);
 int hid_wait_io(struct hid_device* hid);
 
 
diff -u b/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- b/drivers/usb/input/hiddev.c	2005-02-28 17:23:09 -08:00
+++ b/drivers/usb/input/hiddev.c	2005-02-28 17:20:09 -08:00
@@ -124,6 +124,7 @@
 	int i, j;
 	struct hid_report *report;
 	struct hid_report_enum *report_enum;
+	struct list_head *list;
 	struct hid_field *field;
 
 	if (uref->report_type < HID_REPORT_TYPE_MIN ||
@@ -131,8 +132,9 @@
 
 	report_enum = hid->report_enum +
 		(uref->report_type - HID_REPORT_TYPE_MIN);
-
-	list_for_each_entry(report, &report_enum->report_list, list)
+	list = report_enum->report_list.next;
+	while (list != &report_enum->report_list) {
+		report = (struct hid_report *) list;
 		for (i = 0; i < report->maxfield; i++) {
 			field = report->field[i];
 			for (j = 0; j < field->maxusage; j++) {
@@ -144,6 +146,8 @@
 				}
 			}
 		}
+		list = list->next;
+	}
 
 	return NULL;
 }
reverted:
--- b/drivers/usb/input/mtouchusb.c	2005-02-28 17:23:09 -08:00
+++ a/drivers/usb/input/mtouchusb.c	2005-02-28 17:23:09 -08:00
@@ -123,7 +123,7 @@
         input_report_abs(&mtouch->input, ABS_X,
                          MTOUCHUSB_GET_XC(mtouch->data));
         input_report_abs(&mtouch->input, ABS_Y,
+                         MTOUCHUSB_GET_YC(mtouch->data));
-                         MTOUCHUSB_MAX_YC - MTOUCHUSB_GET_YC(mtouch->data));
         input_sync(&mtouch->input);
 
 exit:
reverted:
--- b/drivers/usb/input/pid.c	2005-02-28 17:23:09 -08:00
+++ a/drivers/usb/input/pid.c	2005-02-28 17:23:09 -08:00
@@ -48,96 +48,106 @@
 /* Called when a transfer is completed */
 static void hid_pid_ctrl_out(struct urb *u, struct pt_regs *regs)
 {
+    dev_dbg(&u->dev->dev, "hid_pid_ctrl_out - Transfer Completed\n");
-	dev_dbg(&u->dev->dev, "hid_pid_ctrl_out - Transfer Completed\n");
 }
 
+static void hid_pid_exit(struct hid_device* hid)
-static void hid_pid_exit(struct hid_device *hid)
 {
+    struct hid_ff_pid *private = hid->ff_private;
+    
+    if (private->urbffout) {
+	usb_kill_urb(private->urbffout);
+	usb_free_urb(private->urbffout);
+    }
-	struct hid_ff_pid *private = hid->ff_private;
-
-	if (private->urbffout) {
-		usb_kill_urb(private->urbffout);
-		usb_free_urb(private->urbffout);
-	}
 }
 
+static int pid_upload_periodic(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update) {
+    dev_info(&pid->hid->dev->dev, "requested periodic force upload\n");
+    return 0;
-static int pid_upload_periodic(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "requested periodic force upload\n");
-	return 0;
 }
 
+static int pid_upload_constant(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update) {
+    dev_info(&pid->hid->dev->dev, "requested constant force upload\n");
+    return 0;
-static int pid_upload_constant(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "requested constant force upload\n");
-	return 0;
 }
 
+static int pid_upload_condition(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update) {
+    dev_info(&pid->hid->dev->dev, "requested Condition force upload\n");
+    return 0;
-static int pid_upload_condition(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "requested Condition force upload\n");
-	return 0;
 }
 
+static int pid_upload_ramp(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update) {
+    dev_info(&pid->hid->dev->dev, "request ramp force upload\n");
+    return 0;
-static int pid_upload_ramp(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
-	dev_info(&pid->hid->dev->dev, "request ramp force upload\n");
-	return 0;
 }
 
 static int hid_pid_event(struct hid_device *hid, struct input_dev *input,
+			  unsigned int type, unsigned int code, int value)
-			 unsigned int type, unsigned int code, int value)
 {
+    dev_dbg(&hid->dev->dev, "PID event received: type=%d,code=%d,value=%d.\n", type, code, value);
-	dev_dbg(&hid->dev->dev, "PID event received: type=%d,code=%d,value=%d.\n", type, code, value);
 
+    if (type != EV_FF)
+	return -1;
-	if (type != EV_FF)
-		return -1;
 
+    
+
+    return 0;
-	return 0;
 }
 
 /* Lock must be held by caller */
+static void hid_pid_ctrl_playback(struct hid_device *hid,
+				   struct hid_pid_effect *effect, int play)
-static void hid_pid_ctrl_playback(struct hid_device *hid, struct hid_pid_effect *effect, int play)
 {
+	if (play) {
-	if (play)
 		set_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
+
+	} else {
-	else
 		clear_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
+	}
 }
 
+
 static int hid_pid_erase(struct input_dev *dev, int id)
 {
 	struct hid_device *hid = dev->private;
+	struct hid_field* field;
+	struct hid_report* report;
 	struct hid_ff_pid *pid = hid->ff_private;
-	struct hid_field *field;
 	unsigned long flags;
+	unsigned wanted_report = HID_UP_PID | FF_PID_USAGE_BLOCK_FREE;  /*  PID Block Free Report */
 	int ret;
 
 	if (!CHECK_OWNERSHIP(id, pid))
 		return -EACCES;
 
 	/* Find report */
+	ret =  hid_find_report_by_usage(hid, wanted_report, &report, HID_OUTPUT_REPORT);
+	if(!ret) {
-	field = hid_find_field_by_usage(hid, HID_UP_PID | FF_PID_USAGE_BLOCK_FREE,
-					HID_OUTPUT_REPORT);
-	if (!field) {
 		dev_err(&hid->dev->dev, "couldn't find report\n");
+		return ret;
+	}
+
+	/* Find field */
+	field = (struct hid_field *) kmalloc(sizeof(struct hid_field), GFP_KERNEL);
+	if(!field) {
+		dev_err(&hid->dev->dev, "couldn't allocate field\n");
+		return -ENOMEM;
-		return -EIO;
 	}
 
+	ret = hid_set_field(field, ret, pid->effects[id].device_id);
+	if(!ret) {
-	ret = hid_set_field(field, 0, pid->effects[id].device_id);
-	if (ret) {
 		dev_err(&hid->dev->dev, "couldn't set field\n");
 		return ret;
 	}
 
+	hid_submit_report(hid, report, USB_DIR_OUT);
-	hid_submit_report(hid, field->report, USB_DIR_OUT);
 
 	spin_lock_irqsave(&pid->lock, flags);
 	hid_pid_ctrl_playback(hid, pid->effects + id, 0);
 	pid->effects[id].flags = 0;
 	spin_unlock_irqrestore(&pid->lock, flags);
 
+	return ret;
-	return 0;
 }
 
 /* Erase all effects this process owns */
@@ -148,32 +158,31 @@
 	int i;
 
 	/*NOTE: no need to lock here. The only times EFFECT_USED is
+	  modified is when effects are uploaded or when an effect is
+	  erased. But a process cannot close its dev/input/eventX fd
+	  and perform ioctls on the same fd all at the same time */
+	for (i=0; i<dev->ff_effects_max; ++i)
+		if ( current->pid == pid->effects[i].owner
+		     && test_bit(FF_PID_FLAGS_USED, &pid->effects[i].flags))
-	   modified is when effects are uploaded or when an effect is
-	   erased. But a process cannot close its dev/input/eventX fd
-	   and perform ioctls on the same fd all at the same time */
-	/*FIXME: multiple threads, anyone? */
-	for (i = 0; i < dev->ff_effects_max; ++i)
-		if (current->pid == pid->effects[i].owner
-		    && test_bit(FF_PID_FLAGS_USED, &pid->effects[i].flags))
 			if (hid_pid_erase(dev, i))
 				dev_warn(&hid->dev->dev, "erase effect %d failed", i);
 
 	return 0;
 }
 
+
 static int hid_pid_upload_effect(struct input_dev *dev,
+				  struct ff_effect *effect)
-				 struct ff_effect *effect)
 {
+	struct hid_ff_pid* pid_private  = (struct hid_ff_pid*)(dev->private);
-	struct hid_ff_pid *pid_private = (struct hid_ff_pid *)(dev->private);
 	int ret;
 	int is_update;
+	unsigned long flags = 0;
-	unsigned long flags;
 
+        dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n",effect->type);
-	dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n", effect->type);
 	/* Check this effect type is supported by this device */
 	if (!test_bit(effect->type, dev->ffbit)) {
+		dev_dbg(&pid_private->hid->dev->dev, "invalid kind of effect requested.\n");
-		dev_dbg(&pid_private->hid->dev->dev,
-			"invalid kind of effect requested.\n");
 		return -EINVAL;
 	}
 
@@ -181,30 +190,31 @@
 	 * If we want to create a new effect, get a free id
 	 */
 	if (effect->id == -1) {
+		int id=0;
-		int id = 0;
 
 		// Spinlock so we don`t get a race condition when choosing IDs
 		spin_lock_irqsave(&pid_private->lock, flags);
 
+		while(id < FF_EFFECTS_MAX)
+			if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags)) 
+			    break;
-		while (id < FF_EFFECTS_MAX)
-			if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags))
-				break;
 
+		if ( id == FF_EFFECTS_MAX) {
+			spin_unlock_irqrestore(&pid_private->lock,flags);
-		if (id == FF_EFFECTS_MAX) {
-			spin_unlock_irqrestore(&pid_private->lock, flags);
 // TEMP - We need to get ff_effects_max correctly first:  || id >= dev->ff_effects_max) {
 			dev_dbg(&pid_private->hid->dev->dev, "Not enough device memory\n");
 			return -ENOMEM;
 		}
 
 		effect->id = id;
+		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.",id);
-		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.", id);
 		pid_private->effects[id].owner = current->pid;
+		pid_private->effects[id].flags = (1<<FF_PID_FLAGS_USED);
+		spin_unlock_irqrestore(&pid_private->lock,flags);
-		pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
-		spin_unlock_irqrestore(&pid_private->lock, flags);
 
 		is_update = FF_PID_FALSE;
+	}
+	else {
-	} else {
 		/* We want to update an effect */
 		if (!CHECK_OWNERSHIP(effect->id, pid_private))
 			return -EACCES;
@@ -214,8 +224,9 @@
 			return -EINVAL;
 
 		/* Check the effect is not already being updated */
+		if (test_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags)) {
-		if (test_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags))
 			return -EAGAIN;
+		}
 
 		is_update = FF_PID_TRUE;
 	}
@@ -224,30 +235,28 @@
 	 * Upload the effect
 	 */
 	switch (effect->type) {
+		case FF_PERIODIC:
+			ret = pid_upload_periodic(pid_private, effect, is_update);
+			break;
+
+		case FF_CONSTANT:
+			ret = pid_upload_constant(pid_private, effect, is_update);
+			break;
+
+		case FF_SPRING:
+		case FF_FRICTION:
+		case FF_DAMPER:
+		case FF_INERTIA:
+			ret = pid_upload_condition(pid_private, effect, is_update);
+			break;
+
+		case FF_RAMP:
+			ret = pid_upload_ramp(pid_private, effect, is_update);
+			break;
+
+		default:
+			dev_dbg(&pid_private->hid->dev->dev, "invalid type of effect requested - %x.\n", effect->type);
+			return -EINVAL;
-	case FF_PERIODIC:
-		ret = pid_upload_periodic(pid_private, effect, is_update);
-		break;
-
-	case FF_CONSTANT:
-		ret = pid_upload_constant(pid_private, effect, is_update);
-		break;
-
-	case FF_SPRING:
-	case FF_FRICTION:
-	case FF_DAMPER:
-	case FF_INERTIA:
-		ret = pid_upload_condition(pid_private, effect, is_update);
-		break;
-
-	case FF_RAMP:
-		ret = pid_upload_ramp(pid_private, effect, is_update);
-		break;
-
-	default:
-		dev_dbg(&pid_private->hid->dev->dev,
-			"invalid type of effect requested - %x.\n",
-			effect->type);
-		return -EINVAL;
 	}
 	/* If a packet was sent, forbid new updates until we are notified
 	 * that the packet was updated
@@ -260,36 +269,37 @@
 
 int hid_pid_init(struct hid_device *hid)
 {
+    struct hid_ff_pid *private;
+    struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
-	struct hid_ff_pid *private;
-	struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
 
+    private = hid->ff_private = kmalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
+    if (!private) return -1;
+    
+    memset(private,0,sizeof(struct hid_ff_pid));
+
+    hid->ff_private = private; /* 'cause memset can move the block away */
+
+    private->hid = hid;
+    
+    hid->ff_exit = hid_pid_exit;
+    hid->ff_event = hid_pid_event;
+    
+    /* Open output URB */
+    if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) {
+	kfree(private);
+	return -1;
+    }
+
+    usb_fill_control_urb(private->urbffout, hid->dev,0,(void *) &private->ffcr,private->ctrl_buffer,8,hid_pid_ctrl_out,hid);
+    hidinput->input.upload_effect = hid_pid_upload_effect;
+    hidinput->input.flush = hid_pid_flush;
+    hidinput->input.ff_effects_max = 8;  // A random default
+    set_bit(EV_FF, hidinput->input.evbit);
+    set_bit(EV_FF_STATUS, hidinput->input.evbit);
+
+    spin_lock_init(&private->lock);
+
+    printk(KERN_INFO "Force feedback driver for PID devices by Rodrigo Damazio <rdamazio@lsi.usp.br>.\n");
+    
+    return 0;    
-	private = hid->ff_private = kcalloc(1, sizeof(struct hid_ff_pid), GFP_KERNEL);
-	if (!private)
-		return -ENOMEM;
-
-	private->hid = hid;
-
-	hid->ff_exit = hid_pid_exit;
-	hid->ff_event = hid_pid_event;
-
-	/* Open output URB */
-	if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) {
-		kfree(private);
-		return -1;
-	}
-
-	usb_fill_control_urb(private->urbffout, hid->dev, 0,
-			     (void *)&private->ffcr, private->ctrl_buffer, 8,
-			     hid_pid_ctrl_out, hid);
-	hidinput->input.upload_effect = hid_pid_upload_effect;
-	hidinput->input.flush = hid_pid_flush;
-	hidinput->input.ff_effects_max = 8;	// A random default
-	set_bit(EV_FF, hidinput->input.evbit);
-	set_bit(EV_FF_STATUS, hidinput->input.evbit);
-
-	spin_lock_init(&private->lock);
-
-	printk(KERN_INFO "Force feedback driver for PID devices by Rodrigo Damazio <rdamazio@lsi.usp.br>.\n");
-
-	return 0;
 }
reverted:
--- b/drivers/usb/input/pid.h	2005-02-28 17:23:08 -08:00
+++ a/drivers/usb/input/pid.h	2005-02-28 17:23:08 -08:00
@@ -25,31 +25,31 @@
 
 #define FF_EFFECTS_MAX 64
 
+#define FF_PID_FLAGS_USED	1  /* If the effect exists */
+#define FF_PID_FLAGS_UPDATING	2  /* If the effect is being updated */
+#define FF_PID_FLAGS_PLAYING	3  /* If the effect is currently being played */
-#define FF_PID_FLAGS_USED	1	/* If the effect exists */
-#define FF_PID_FLAGS_UPDATING	2	/* If the effect is being updated */
-#define FF_PID_FLAGS_PLAYING	3	/* If the effect is currently being played */
 
 #define FF_PID_FALSE	0
 #define FF_PID_TRUE	1
 
 struct hid_pid_effect {
+    unsigned long flags;
+    pid_t owner;
+    unsigned int device_id;  // The device-assigned ID
+    struct ff_effect effect;
-	unsigned long flags;
-	pid_t owner;
-	unsigned int device_id;	/* The device-assigned ID */
-	struct ff_effect effect;
 };
 
 struct hid_ff_pid {
+    struct hid_device *hid;
+    unsigned long int gain;
-	struct hid_device *hid;
-	unsigned long gain;
 
+    struct urb *urbffout;
+    struct usb_ctrlrequest ffcr;
+    spinlock_t lock;
-	struct urb *urbffout;
-	struct usb_ctrlrequest ffcr;
-	spinlock_t lock;
 
+    char ctrl_buffer[8];
-	unsigned char ctrl_buffer[8];
 
+    struct hid_pid_effect effects[FF_EFFECTS_MAX];
-	struct hid_pid_effect effects[FF_EFFECTS_MAX];
 };
 
 /*
diff -u b/include/linux/gameport.h b/include/linux/gameport.h
--- b/include/linux/gameport.h	2005-02-28 17:23:09 -08:00
+++ b/include/linux/gameport.h	2005-02-28 17:20:10 -08:00
@@ -30,12 +30,6 @@
 	int (*open)(struct gameport *, int);
 	void (*close)(struct gameport *);
 
-	struct timer_list poll_timer;
-	unsigned int poll_interval;	/* in msecs */
-	spinlock_t timer_lock;
-	unsigned int poll_cnt;
-	void (*poll_handler)(struct gameport *);
-
 	struct gameport *parent, *child;
 
 	struct gameport_driver *drv;
@@ -184,15 +178,2 @@
 
-static inline void gameport_set_poll_handler(struct gameport *gameport, void (*handler)(struct gameport *))
-{
-	gameport->poll_handler = handler;
-}
-
-static inline void gameport_set_poll_interval(struct gameport *gameport, unsigned int msecs)
-{
-	gameport->poll_interval = msecs;
-}
-
-void gameport_start_polling(struct gameport *gameport);
-void gameport_stop_polling(struct gameport *gameport);
-
 #endif
reverted:
--- b/include/linux/hiddev.h	2005-02-28 17:23:08 -08:00
+++ a/include/linux/hiddev.h	2005-02-28 17:23:08 -08:00
@@ -201,8 +201,8 @@
  *		ioctl(fd, HIDIOCGUSAGE, &uref);
  *          }
  *	}
+ *	uref.report_id |= HID_REPORT_ID_NEXT;
+ *	ret = ioctl(fd, HIDIOCGREPORTINFO, &uref);
- *	rinfo.report_id |= HID_REPORT_ID_NEXT;
- *	ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
  *  }
  */
 
reverted:
--- b/include/linux/input.h	2005-02-28 17:23:09 -08:00
+++ a/include/linux/input.h	2005-02-28 17:23:09 -08:00
@@ -12,7 +12,6 @@
 #ifdef __KERNEL__
 #include <linux/time.h>
 #include <linux/list.h>
-#include <linux/device.h>
 #else
 #include <sys/time.h>
 #include <sys/ioctl.h>
@@ -772,7 +771,7 @@
 #include <linux/fs.h>
 #include <linux/timer.h>
 
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define NBITS(x) (((x)/BITS_PER_LONG)+1)
 #define BIT(x)	(1UL<<((x)%BITS_PER_LONG))
 #define LONG(x) ((x)/BITS_PER_LONG)
 
@@ -856,7 +855,6 @@
 
 	struct input_handle *grab;
 	struct device *dev;
-	struct class_device cdev;
 
 	struct list_head	h_list;
 	struct list_head	node;
reverted:
--- b/include/linux/joystick.h	2005-02-28 17:23:09 -08:00
+++ a/include/linux/joystick.h	2005-02-28 17:23:09 -08:00
@@ -66,10 +66,10 @@
 #define JSIOCSCORR		_IOW('j', 0x21, struct js_corr)			/* set correction values */
 #define JSIOCGCORR		_IOR('j', 0x22, struct js_corr)			/* get correction values */
 
+#define JSIOCSAXMAP		_IOW('j', 0x31, __u8[ABS_MAX])			/* set axis mapping */
+#define JSIOCGAXMAP		_IOR('j', 0x32, __u8[ABS_MAX])			/* get axis mapping */
+#define JSIOCSBTNMAP		_IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC])	/* set button mapping */
+#define JSIOCGBTNMAP		_IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC])	/* get button mapping */
-#define JSIOCSAXMAP		_IOW('j', 0x31, __u8[ABS_MAX + 1])		/* set axis mapping */
-#define JSIOCGAXMAP		_IOR('j', 0x32, __u8[ABS_MAX + 1])		/* get axis mapping */
-#define JSIOCSBTNMAP		_IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC + 1])	/* set button mapping */
-#define JSIOCGBTNMAP		_IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC + 1])	/* get button mapping */
 
 /*
  * Types and constants for get/set correction
reverted:
--- b/include/linux/keyboard.h	2005-02-28 17:23:08 -08:00
+++ a/include/linux/keyboard.h	2005-02-28 17:23:08 -08:00
@@ -16,7 +16,7 @@
 
 #define NR_SHIFT	9
 
+#define NR_KEYS		255
-#define NR_KEYS		256
 #define MAX_NR_KEYMAPS	256
 /* This means 128Kb if all keymaps are allocated. Only the superuser
 	may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
reverted:
--- b/include/linux/mod_devicetable.h	2005-02-28 17:23:09 -08:00
+++ a/include/linux/mod_devicetable.h	2005-02-28 17:23:09 -08:00
@@ -165,14 +165,4 @@
 };
 
 
-#define SERIO_ANY	0xff
-
-struct serio_device_id {
-	__u8 type;
-	__u8 extra;
-	__u8 id;
-	__u8 proto;
-};
-
-
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff -u b/include/linux/serio.h b/include/linux/serio.h
--- b/include/linux/serio.h	2005-02-28 17:23:09 -08:00
+++ b/include/linux/serio.h	2005-02-28 17:20:09 -08:00
@@ -19,7 +19,13 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
-#include <linux/mod_devicetable.h>
+
+struct serio_device_id {
+	unsigned char type;
+	unsigned char extra;
+	unsigned char id;
+	unsigned char proto;
+};
 
 struct serio {
 	void *port_data;
@@ -168,6 +174,8 @@
 #define SERIO_PARITY	2
 #define SERIO_FRAME	4
 
+#define SERIO_ANY	0xff
+
 /*
  * Serio types
  */
reverted:
--- b/scripts/mod/file2alias.c	2005-02-28 17:23:09 -08:00
+++ a/scripts/mod/file2alias.c	2005-02-28 17:23:09 -08:00
@@ -4,7 +4,7 @@
  *
  * Copyright 2002-2003  Rusty Russell, IBM Corporation
  *           2003       Kai Germaschewski
+ *           
- *
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -181,24 +181,6 @@
 	return 1;
 }
 
-/* Looks like: "serio:tyNprNidNexN" */
-static int do_serio_entry(const char *filename,
-			  struct serio_device_id *id, char *alias)
-{
-	id->type = TO_NATIVE(id->type);
-	id->proto = TO_NATIVE(id->proto);
-	id->id = TO_NATIVE(id->id);
-	id->extra = TO_NATIVE(id->extra);
-
-	strcpy(alias, "serio:");
-	ADD(alias, "ty", id->type != SERIO_ANY, id->type);
-	ADD(alias, "pr", id->proto != SERIO_ANY, id->proto);
-	ADD(alias, "id", id->id != SERIO_ANY, id->id);
-	ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
-
-	return 1;
-}
-
 /* looks like: "pnp:dD" */
 static int do_pnp_entry(const char *filename,
 			struct pnp_device_id *id, char *alias)
@@ -288,9 +270,6 @@
 	else if (sym_is(symname, "__mod_ccw_device_table"))
 		do_table(symval, sym->st_size, sizeof(struct ccw_device_id),
 			 do_ccw_entry, mod);
-	else if (sym_is(symname, "__mod_serio_device_table"))
-		do_table(symval, sym->st_size, sizeof(struct serio_device_id),
-			 do_serio_entry, mod);
 	else if (sym_is(symname, "__mod_pnp_device_table"))
 		do_table(symval, sym->st_size, sizeof(struct pnp_device_id),
 			 do_pnp_entry, mod);