On Tue, 26 Sep 2006 23:37:29 -0700 Andrew Morton <[EMAIL PROTECTED]> wrote:
> With git-input.patch applied, my wireless USB mouse doesn't work. OK, I did a round of restesting. I haven't seen the oopses again, but I didn't try terribly hard. The mouse-dies-after-one-second bug is still there. Bisection shows that it's caused by this: commit 0bfb22b4308bea5e7afd9434ac7e937b12fc5915 Author: Dmitry Torokhov <[EMAIL PROTECTED]> Date: Sun Oct 1 23:50:26 2006 -0400 Input: make input_{open|close}_device() more robust - add "dead" flag to input_dev structure and check the flag when opening, closing or trying to flush input device - fix error handling in input_open_device (was leaving device "used") - allow input_close_device() to be safely called for already closed devices Signed-off-by: Dmitry Torokhov <[EMAIL PROTECTED]> diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 7f87c4b..b71e2f3 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -23,8 +23,7 @@ #include <linux/device.h> #include <linux/compat.h> struct evdev { - int exist; - int open; + int dead; int minor; char name[16]; struct input_handle handle; @@ -90,9 +89,6 @@ static int evdev_flush(struct file *file { struct evdev_list *list = file->private_data; - if (!list->evdev->exist) - return -ENODEV; - return input_flush_device(&list->evdev->handle, file); } @@ -119,9 +115,7 @@ static int evdev_release(struct inode *i list_del(&list->node); kfree(list); - if (!--evdev->open && evdev->exist) - input_close_device(&evdev->handle); - + input_close_device(&evdev->handle); kref_put(&evdev->kref, evdev_free); return 0; @@ -131,13 +125,14 @@ static int evdev_open(struct inode *inod { struct evdev_list *list; struct evdev *evdev; + int error; int i = iminor(inode) - EVDEV_MINOR_BASE; if (i >= EVDEV_MINORS) return -ENODEV; evdev = evdev_table[i]; - if (!evdev || !evdev->exist) + if (!evdev || evdev->dead) return -ENODEV; list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL); @@ -150,10 +145,16 @@ static int evdev_open(struct inode *inod list_add_tail(&list->node, &evdev->list); file->private_data = list; - if (!evdev->open++ && evdev->exist) - input_open_device(&evdev->handle); + error = input_open_device(&evdev->handle); + if (error) + goto fail; return 0; + + fail: list_del(&list->node); + kfree(list); + kref_put(&evdev->kref, evdev_free); + return error; } #ifdef CONFIG_COMPAT @@ -254,44 +255,46 @@ static int evdev_event_to_user(char __us #endif /* CONFIG_COMPAT */ -static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) +static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct evdev_list *list = file->private_data; + struct evdev *evdev = list->evdev; struct input_event event; int retval = 0; - if (!list->evdev->exist) + if (evdev->dead) return -ENODEV; while (retval < count) { if (evdev_event_from_user(buffer + retval, &event)) return -EFAULT; - input_inject_event(&list->evdev->handle, event.type, event.code, event.value); + input_inject_event(&evdev->handle, event.type, event.code, event.value); retval += evdev_event_size(); } return retval; } -static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) +static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct evdev_list *list = file->private_data; + struct evdev *evdev = list->evdev; int retval; if (count < evdev_event_size()) return -EINVAL; - if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) + if (list->head == list->tail && !evdev->dead && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->evdev->wait, - list->head != list->tail || (!list->evdev->exist)); + retval = wait_event_interruptible(evdev->wait, + list->head != list->tail || evdev->dead); if (retval) return retval; - if (!list->evdev->exist) + if (evdev->dead) return -ENODEV; while (list->head != list->tail && retval + evdev_event_size() <= count) { @@ -312,10 +315,11 @@ static ssize_t evdev_read(struct file * static unsigned int evdev_poll(struct file *file, poll_table *wait) { struct evdev_list *list = file->private_data; + struct evdev *evdev = list->evdev; - poll_wait(file, &list->evdev->wait, wait); - return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | - (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &evdev->wait, wait); + return (list->head != list->tail ? POLLIN | POLLRDNORM : 0) | + (evdev->dead ? POLLHUP | POLLERR : 0); } #ifdef CONFIG_COMPAT @@ -407,7 +411,7 @@ static long evdev_ioctl_handler(struct f int i, t, u, v; int error; - if (!evdev->exist) + if (evdev->dead) return -ENODEV; switch (cmd) { @@ -650,7 +654,6 @@ static int evdev_connect(struct input_ha INIT_LIST_HEAD(&evdev->list); init_waitqueue_head(&evdev->wait); - evdev->exist = 1; evdev->minor = minor; evdev->handle.dev = dev; evdev->handle.name = evdev->name; @@ -698,15 +701,11 @@ static void evdev_disconnect(struct inpu sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); - evdev->exist = 0; - - if (evdev->open) { - input_flush_device(handle, NULL); - input_close_device(handle); - wake_up_interruptible(&evdev->wait); - list_for_each_entry(list, &evdev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); - } + + evdev->dead = 1; + wake_up_interruptible(&evdev->wait); + list_for_each_entry(list, &evdev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); kref_put(&evdev->kref, evdev_free); } diff --git a/drivers/input/input.c b/drivers/input/input.c index 5ac4a28..6ff85ca 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -261,26 +261,43 @@ int input_open_device(struct input_handl if (err) return err; + if (dev->dead) { + err = -ENODEV; + goto out; + } + handle->open++; - if (!dev->users++ && dev->open) + if (!dev->users++ && dev->open) { err = dev->open(dev); + if (err) { + dev->users--; + handle->open--; + } + } - if (err) - handle->open--; - + out: mutex_unlock(&dev->mutex); - return err; } EXPORT_SYMBOL(input_open_device); -int input_flush_device(struct input_handle* handle, struct file* file) +int input_flush_device(struct input_handle *handle, struct file *file) { - if (handle->dev->flush) - return handle->dev->flush(handle->dev, file); + struct input_dev *dev = handle->dev; + int ret; - return 0; + mutex_lock(&dev->mutex); + + if (dev->dead) + ret = -ENODEV; + else if (dev->flush) + ret = dev->flush(dev, file); + else + ret = 0; + + mutex_unlock(&dev->mutex); + return ret; } EXPORT_SYMBOL(input_flush_device); @@ -292,9 +309,14 @@ void input_close_device(struct input_han mutex_lock(&dev->mutex); - if (!--dev->users && dev->close) - dev->close(dev); - handle->open--; + if (handle->open) { + if (dev->users) { + if (dev->close && !dev->dead) + dev->close(dev); + dev->users--; + } + handle->open--; + } mutex_unlock(&dev->mutex); } @@ -1029,14 +1051,19 @@ void input_unregister_device(struct inpu list_del_init(&dev->node); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); - mutex_lock(&dev->mutex); + if (dev->flush) + dev->flush(dev, NULL); + if (dev->users && dev->close) + dev->close(dev); dev->name = dev->phys = dev->uniq = NULL; + dev->dead = 1; mutex_unlock(&dev->mutex); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); + class_device_unregister(&dev->cdev); input_wakeup_procfs_readers(); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index aa5ddef..67a3c68 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -37,8 +37,7 @@ #define JOYDEV_MINORS 16 #define JOYDEV_BUFFER_SIZE 64 struct joydev { - int exist; - int open; + int dead; int minor; char name[16]; struct input_handle handle; @@ -159,9 +158,7 @@ static int joydev_release(struct inode * list_del(&list->node); kfree(list); - if (!--joydev->open && joydev->exist) - input_close_device(&list->joydev->handle); - + input_close_device(&joydev->handle); kref_put(&joydev->kref, joydev_free); return 0; @@ -171,13 +168,14 @@ static int joydev_open(struct inode *ino { struct joydev_list *list; struct joydev *joydev; + int error; int i = iminor(inode) - JOYDEV_MINOR_BASE; if (i >= JOYDEV_MINORS) return -ENODEV; joydev = joydev_table[i]; - if (!joydev || !joydev->exist) + if (!joydev || joydev->dead) return -ENODEV; list = kzalloc(sizeof(struct joydev_list), GFP_KERNEL); @@ -190,10 +188,16 @@ static int joydev_open(struct inode *ino list_add_tail(&list->node, &joydev->list); file->private_data = list; - if (!joydev->open++ && joydev->exist) - input_open_device(&list->joydev->handle); + error = input_open_device(&joydev->handle); + if (error) + goto fail; return 0; + + fail: list_del(&list->node); + kfree(list); + kref_put(&joydev->kref, joydev_free); + return error; } static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) @@ -208,7 +212,7 @@ static ssize_t joydev_read(struct file * struct input_dev *input = joydev->handle.dev; int retval = 0; - if (!joydev->exist) + if (joydev->dead) return -ENODEV; if (count < sizeof(struct js_event)) @@ -237,15 +241,15 @@ static ssize_t joydev_read(struct file * list->head == list->tail && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->joydev->wait, - !list->joydev->exist || + retval = wait_event_interruptible(joydev->wait, + joydev->dead || list->startup < joydev->nabs + joydev->nkey || list->head != list->tail); if (retval) return retval; - if (!list->joydev->exist) + if (joydev->dead) return -ENODEV; while (list->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { @@ -287,10 +291,12 @@ static ssize_t joydev_read(struct file * static unsigned int joydev_poll(struct file *file, poll_table *wait) { struct joydev_list *list = file->private_data; + struct joydev *joydev = list->joydev; - poll_wait(file, &list->joydev->wait, wait); - return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? - (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &joydev->wait, wait); + return (list->head != list->tail || + list->startup < joydev->nabs + joydev->nkey ? POLLIN | POLLRDNORM : 0) | + (joydev->dead ? POLLHUP | POLLERR : 0); } static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp) @@ -391,7 +397,7 @@ static long joydev_compat_ioctl(struct f struct JS_DATA_SAVE_TYPE_32 ds32; int err; - if (!joydev->exist) + if (joydev->dead) return -ENODEV; switch(cmd) { @@ -442,7 +448,7 @@ static int joydev_ioctl(struct inode *in struct joydev *joydev = list->joydev; void __user *argp = (void __user *)arg; - if (!joydev->exist) + if (joydev->dead) return -ENODEV; switch(cmd) { @@ -499,7 +505,6 @@ static int joydev_connect(struct input_h init_waitqueue_head(&joydev->wait); joydev->minor = minor; - joydev->exist = 1; joydev->handle.dev = dev; joydev->handle.name = joydev->name; joydev->handle.handler = handler; @@ -586,14 +591,11 @@ static void joydev_disconnect(struct inp sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); - joydev->exist = 0; - if (joydev->open) { - input_close_device(handle); - wake_up_interruptible(&joydev->wait); - list_for_each_entry(list, &joydev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); - } + joydev->dead = 1; + wake_up_interruptible(&joydev->wait); + list_for_each_entry(list, &joydev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); kref_put(&joydev->kref, joydev_free); } diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 685a622..3c3ff63 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -58,8 +58,7 @@ struct mousedev_hw_data { }; struct mousedev { - int exist; - int open; + int dead; int minor; char name[16]; struct input_handle handle; @@ -112,6 +111,7 @@ static struct input_handler mousedev_han static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; static struct mousedev mousedev_mix; +static int mousedev_mix_open; #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) @@ -371,11 +371,12 @@ static void mixdev_release(void) { struct input_handle *handle; + mousedev_mix_open--; + list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { struct mousedev *mousedev = handle->private; - if (!mousedev->open && mousedev->exist) - input_close_device(&mousedev->handle); + input_close_device(handle); kref_put(&mousedev->kref, mousedev_free); } } @@ -390,12 +391,10 @@ static int mousedev_release(struct inode list_del(&list->node); kfree(list); - if (!--mousedev->open) { - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_release(); - else if (!mousedev_mix.open && mousedev->exist) - input_close_device(&mousedev->handle); - } + if (mousedev->minor == MOUSEDEV_MIX) + mixdev_release(); + else + input_close_device(&mousedev->handle); kref_put(&mousedev->kref, mousedev_free); @@ -407,6 +406,7 @@ static int mousedev_open(struct inode *i struct mousedev_list *list; struct input_handle *handle; struct mousedev *mousedev, *md; + int error; int i; #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -420,7 +420,7 @@ #endif return -ENODEV; mousedev = mousedev_table[i]; - if (!mousedev || !mousedev->exist) + if (!mousedev || mousedev->dead) return -ENODEV; list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL); @@ -436,17 +436,21 @@ #endif list_add_tail(&list->node, &mousedev->list); file->private_data = list; - if (!mousedev->open++) { - if (mousedev->minor == MOUSEDEV_MIX) { - list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { - md = handle->private; - kref_get(&md->kref); - if (!md->open && md->exist) - input_open_device(handle); - } - } else - if (!mousedev_mix.open && mousedev->exist) - input_open_device(&mousedev->handle); + if (mousedev->minor == MOUSEDEV_MIX) { + mousedev_mix_open++; + list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { + md = handle->private; + kref_get(&md->kref); + input_open_device(handle); + } + } else { + error = input_open_device(&mousedev->handle); + if (error) { + list_del(&list->node); + kfree(list); + kref_put(&mousedev->kref, mousedev_free); + return error; + } } return 0; @@ -581,18 +585,19 @@ static ssize_t mousedev_write(struct fil static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) { struct mousedev_list *list = file->private_data; + struct mousedev *mousedev = list->mousedev; int retval = 0; if (!list->ready && !list->buffer && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(list->mousedev->wait, - !list->mousedev->exist || list->ready || list->buffer); + retval = wait_event_interruptible(mousedev->wait, + mousedev->dead || list->ready || list->buffer); if (retval) return retval; - if (!list->mousedev->exist) + if (mousedev->dead) return -ENODEV; if (!list->buffer && list->ready) { @@ -615,10 +620,11 @@ static ssize_t mousedev_read(struct file static unsigned int mousedev_poll(struct file *file, poll_table *wait) { struct mousedev_list *list = file->private_data; + struct mousedev *mousedev = list->mousedev; - poll_wait(file, &list->mousedev->wait, wait); - return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | - (list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &mousedev->wait, wait); + return (list->ready || list->buffer ? POLLIN | POLLRDNORM : 0) | + (mousedev->dead ? POLLHUP | POLLERR : 0); } static const struct file_operations mousedev_fops = { @@ -655,7 +661,6 @@ static int mousedev_connect(struct input init_waitqueue_head(&mousedev->wait); mousedev->minor = minor; - mousedev->exist = 1; mousedev->handle.dev = dev; mousedev->handle.name = mousedev->name; mousedev->handle.handler = handler; @@ -681,7 +686,7 @@ static int mousedev_connect(struct input if (error) goto err_remove_link; - if (mousedev_mix.open) { + if (mousedev_mix_open) { error = input_open_device(&mousedev->handle); if (error) goto err_unlink_handle; @@ -711,15 +716,11 @@ static void mousedev_disconnect(struct i sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); - mousedev->exist = 0; - if (mousedev->open) { - input_close_device(handle); - wake_up_interruptible(&mousedev->wait); - list_for_each_entry(list, &mousedev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); - } else if (mousedev_mix.open) - input_close_device(handle); + mousedev->dead = 1; + wake_up_interruptible(&mousedev->wait); + list_for_each_entry(list, &mousedev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); kref_put(&mousedev->kref, mousedev_free); } @@ -783,7 +784,6 @@ static int __init mousedev_init(void) kref_init(&mousedev_mix.kref); INIT_LIST_HEAD(&mousedev_mix.list); init_waitqueue_head(&mousedev_mix.wait); - mousedev_mix.exist = 1; mousedev_mix.minor = MOUSEDEV_MIX; mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 123bbe7..d61da4b 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -106,8 +106,7 @@ struct ts_calibration { }; struct tsdev { - int exist; - int open; + int dead; int minor; char name[8]; struct input_handle handle; @@ -148,17 +147,26 @@ static int tsdev_fasync(int fd, struct f return retval < 0 ? retval : 0; } +static void tsdev_free(struct kref *kref) +{ + struct tsdev *tsdev = container_of(kref, struct tsdev, kref); + + tsdev_table[tsdev->minor] = NULL; + kfree(tsdev); +} + static int tsdev_open(struct inode *inode, struct file *file) { - int i = iminor(inode) - TSDEV_MINOR_BASE; struct tsdev_list *list; struct tsdev *tsdev; + int error; + int i = iminor(inode) - TSDEV_MINOR_BASE; if (i >= TSDEV_MINORS) return -ENODEV; tsdev = tsdev_table[i & TSDEV_MINOR_MASK]; - if (!tsdev || !tsdev->exist) + if (!tsdev || tsdev->dead) return -ENODEV; list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL); @@ -172,18 +180,16 @@ static int tsdev_open(struct inode *inod list_add_tail(&list->node, &tsdev->list); file->private_data = list; - if (!tsdev->open++ && tsdev->exist) - input_open_device(&list->tsdev->handle); + error = input_open_device(&tsdev->handle); + if (error) + goto fail; return 0; -} -static void tsdev_free(struct kref *kref) -{ - struct tsdev *tsdev = container_of(kref, struct tsdev, kref); - - tsdev_table[tsdev->minor] = NULL; - kfree(tsdev); + fail: list_del(&list->node); + kfree(list); + kref_put(&tsdev->kref, tsdev_free); + return error; } static int tsdev_release(struct inode *inode, struct file *file) @@ -196,9 +202,7 @@ static int tsdev_release(struct inode *i list_del(&list->node); kfree(list); - if (!--tsdev->open && tsdev->exist) - input_close_device(&tsdev->handle); - + input_close_device(&tsdev->handle); kref_put(&tsdev->kref, tsdev_free); return 0; @@ -211,16 +215,16 @@ static ssize_t tsdev_read(struct file *f struct tsdev *tsdev = list->tsdev; int retval = 0; - if (list->head == list->tail && tsdev->exist && (file->f_flags & O_NONBLOCK)) + if (list->head == list->tail && !tsdev->dead && (file->f_flags & O_NONBLOCK)) return -EAGAIN; retval = wait_event_interruptible(tsdev->wait, - list->head != list->tail || !tsdev->exist); + list->head != list->tail || tsdev->dead); if (retval) return retval; - if (!tsdev->exist) + if (tsdev->dead) return -ENODEV; while (list->head != list->tail && @@ -239,10 +243,11 @@ static ssize_t tsdev_read(struct file *f static unsigned int tsdev_poll(struct file *file, poll_table * wait) { struct tsdev_list *list = file->private_data; + struct tsdev *tsdev = list->tsdev; - poll_wait(file, &list->tsdev->wait, wait); - return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | - (list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &tsdev->wait, wait); + return (list->head != list->tail ? POLLIN | POLLRDNORM : 0) | + (tsdev->dead ? POLLHUP | POLLERR : 0); } static int tsdev_ioctl(struct inode *inode, struct file *file, @@ -404,7 +409,6 @@ static int tsdev_connect(struct input_ha sprintf(tsdev->name, "ts%d", minor); - tsdev->exist = 1; tsdev->minor = minor; tsdev->handle.dev = dev; tsdev->handle.name = tsdev->name; @@ -464,14 +468,11 @@ static void tsdev_disconnect(struct inpu sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); - tsdev->exist = 0; - if (tsdev->open) { - input_close_device(handle); - wake_up_interruptible(&tsdev->wait); - list_for_each_entry(list, &tsdev->list, node) - kill_fasync(&list->fasync, SIGIO, POLL_HUP); - } + tsdev->dead = 1; + wake_up_interruptible(&tsdev->wait); + list_for_each_entry(list, &tsdev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); kref_put(&tsdev->kref, tsdev_free); } diff --git a/include/linux/input.h b/include/linux/input.h index 3c42ef9..a5799e7 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -954,7 +954,8 @@ struct input_dev { struct timer_list timer; struct pt_regs *regs; - int state; + + int dead; int sync; ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel