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 * Copyright (c) 2003 Peter Osterlund * Copyright (c) 2004 Dmitry Torokhov - * Copyright (c) 2005 Vojtech Pavlik * * 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 - * Copyright (c) 2005 Vojtech Pavlik * * 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 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; iff_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<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 .\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 .\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 #include -#include #else #include #include @@ -772,7 +771,7 @@ #include #include +#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 #include #include -#include + +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);